HTTP APIs

API (Application Programing Interface)

Provides developers functions, protocols to interact with the database and do actions with any software or application. Appota Pay API was built to deploy applications CARD, SMS, BANK on various programming languages. Payment gateway will be integrated more easier than ever with this protocol.

- Possible to connect in all common programming languages: PHP, C#, JAVA, PYTHON.

- Supporting most of payment services: CARD, SMS, BANK.

Mechanism of operation:

- Connecting via Web Services: HTTP POST/GET

Currently Appota Pay supplies APIs for the following services of payment:

CARD: Support payment by scratch phone cards or game cards.

SMS: Support payment via text messages to short codes.

BANK: Support payment via internet banking.

Document > Appota Ewallet

Appota Ewallet

Conection model


Step 1: Client call to Payota’s API to get payment information. The information is returned link to payment site.

Step 2: Client conduct payment on payment site of Bank side.

Step 3: After Client sent payment requirement, Payota get payment information from provider , and calling to IPN url of Developer (which has been config during making application). After all, Developer will conduct to topup items, services, coin for client.

Step 4: Developer close payment window, then call to API to check transaction, showing notification on Client and finishing transaction.

Description

API Endpoint:
https://api.appotapay.com/v1/services/ewallet/pay?api_key=YOUR_API_KEY&lang=(vi | en)

Method:
HTTP POST

Parametter List

Parametters

Require

main.desciption

Type

developer_trans_id

Yes

Developer's transaction ID (length limit is 5 to 30 characters)

String

amount

Yes

Money amount to charge

String

client_ip

Yes

IP address of user

String

state

No

Contents option, Length limit is less than 150 characters

String

target

No

Contents option, Length limit is less than 150 characters

String

success_url

No

Link will be redirect when transaction success

String

error_url

No

Link will be redirect when transaction fail

String

Response data

Name

Description

Type

error_code

Detail error code

Integer

data

Transaction detail

Object

data.transaction_id

main.transaction_id_des

String

data.developer_trans_id

Developer's transaction ID (length limit is 5 to 30 characters)

String

data.amount

Money amount to charge

String

data.currency

Currency unit

String

data.options

Payment provider list

Array

data.options.url

Link to payment site

String

data.options.vendor

Payment provider

String

message

Transaction note

String

Error Code Board

Error code

Detail

0

Call API successful

1

POST parameters to API is incorrect or error

5

Application is banned or not exists

7

Transaction not exist

11

The system is not support for this card

12

Card format incorrect

13

Developer account is banned or not exists

14

Amount is invalid, must greater than or equal to 10000

15

Transaction ID invalid!

16

Duplicate Transaction ID!

19

Users unrealized transactions

40

Server maintaining, Please try later

41

Transaction are waiting for treatment

91

System error, Please try later

INSTANT PAYMENT NOTIFICATION (IPN) URL

Method:
HTTP POST

Timeout:
10s

Parametter List

Parametters Description Type

status

Transaction status:
1. Successful transaction
0. Failed transaction

Integer

sandbox

1. Test transaction
0. Real trasaction

Integer

transaction_id

Transaction ID

String

developer_trans_id

Partner's transaction ID

String

transaction_type

Transaction type

String

amount

facevalue of transaction

String

currency

Currency unit

String

country_code

Country code

String

state

Value of `state` sent by API

String

target

Value of `target` sent by API

String

vendor

Payment provider (APPOTA)

String

hash

Hash code security is called by Appota system to confirm IPN

hash = md5(amount + country_code + currency + developer_trans_id + sandbox + state + status + target + transaction_id + transaction_type + vendor + secret_key)

Connection string parameter values arranged in order from   (a -> z)

String

Response:
success: http code = 200, body {“error_code”: 0, “message”: “OK”}

POST:
{{http_code}}
                                        {{data_res}}
                                    
Document > iBanking charging

iBanking charging

Conection model


Step 1: Client call to Payota’s API to get payment information. The information is returned link to payment site.

Step 2: Client conduct payment on payment site of Bank side.

Step 3: After Client sent payment requirement, Payota get payment information from provider , and calling to IPN url of Developer (which has been config during making application). After all, Developer will conduct to topup items, services, coin for client.

Step 4: Developer close payment window, then call to API to check transaction, showing notification on Client and finishing transaction.

Description

API Endpoint:
https://api.appotapay.com/v1/services/ibanking?api_key=YOUR_API_KEY&lang=(vi | en)

Sandbox API Endpoint:
https://api.appotapay.com/v1/sandbox/services/ibanking?api_key=YOUR_API_KEY&lang=(vi | en)

Method:
HTTP POST

Parametter List

Parametters

Require

main.desciption

Type

developer_trans_id

Yes

Developer's transaction ID (length limit is 5 to 30 characters)

String

amount

Yes

Money amount to charge

String

bank_id

No

ID of bank

Integer

client_ip

Yes

IP address of user

String

state

No

Contents option, Length limit is less than 150 characters

String

target

No

Contents option, Length limit is less than 150 characters

String

success_url

No

Link will be redirect when transaction success

String

error_url

No

main.error_url_des

String

Response data

Name

Description

Type

error_code

Detail error code

Integer

data

Transaction detail

Object

data.transaction_id

main.transaction_id_des

String

data.developer_trans_id

Developer's transaction ID (length limit is 5 to 30 characters)

String

data.amount

Money amount to charge

String

data.currency

Currency unit

String

data.bank_options

Banking payment provider list

Array

data.bank_options.bank

Name of provider

String

data.bank_options.url

Link to payment site

String

message

Transaction note

String

Table Bank ID

Bank ID

Bank name

1 Vietcombank
2 Techcombank
3 TienPhong Bank
4 Viettin Bank
5 VIB
6 DongA Bank
7 HD Bank
8 MB
9 VietA Bank
10 Maritime Bank
11 Eximbank
12 SHB
14 VP Bank
15 AnBinh Bank
16 SacomBank
17 NamA Bank
18 Ocean Bank
19 BIDV
20 Sea Bank
22 BacA Bank
23 Navibank
24 Agribank
25 Saigonbank
27 PVCombank

Error Code Board

Error code

Detail

0

Call API successful

1

POST parameters to API is incorrect or error

5

Application is banned or not exists

7

Transaction not exist

11

The system is not support for this card

12

Card format incorrect

13

Developer account is banned or not exists

14

Amount is invalid, must greater than or equal to 10000

15

Transaction ID invalid!

16

Duplicate Transaction ID!

19

Users unrealized transactions

40

Server maintaining, Please try later

41

Transaction are waiting for treatment

91

System error, Please try later

INSTANT PAYMENT NOTIFICATION (IPN) URL

Method:
HTTP POST

Timeout:
10s

Parametter List

Parametters Description Type

status

Transaction status:
1. Successful transaction
0. Failed transaction

Integer

sandbox

1. Test transaction
0. Real trasaction

Integer

transaction_id

Transaction ID

String

developer_trans_id

Partner's transaction ID

String

transaction_type

Transaction type

String

amount

facevalue of transaction

String

currency

Currency unit

String

country_code

Country code

String

state

Value of `state` sent by API

String

target

Value of `target` sent by API

String

type

Transaction Type (ATM | VISA)

String

hash

Hash code security is called by Appota system to confirm IPN

hash = md5(amount + country_code + currency + developer_trans_id + sandbox + state + status + target + transaction_id + transaction_type + type + secret_key)

Connection string parameter values arranged in order from   (a -> z)

String

Response:
success: http code = 200, body {“error_code”: 0, “message”: “OK”}


import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
	
public class BankPayment {

    public static final String BANK_PAYMENT_URL = "http://api.appotapay.com/v1/services/ibanking?api_key=";

    public static void main(String[] args) {

            disableSslVerification(); //Enable disableSslVerification function just for testing

            int amount = 50000;//payment amount - VNĐ
            int bank_id = 10;//Bank id = 10 just for testing
            String developer_trans_id = ""; // Set your transaction id
            String apiKey = "your_api_key";
            String success_url = "";//optional - link to redirect to when make payment successfully
            String error_url = "";//optional - link to redirect to if make payment failed
            String state = "my state value";//optional - max 150 characters
            String target = "my target value";//optional - max 150 characters
            String languageCode = "vi";

            BankPayment payConnect = new BankPayment();

            try {
                    payConnect.makeBankPayment(apiKey, developer_trans_id, amount, bank_id, success_url, error_url, state, target, languageCode);
            } catch (Exception e) {
                    e.printStackTrace();
            }
    }

    private  void makeBankPayment(String api_key, String developer_trans_id, int amount,int bank_id,String success_url, String error_url,
        String state, String target,String language_code) throws Exception {

        String url = BANK_PAYMENT_URL +api_key+"&lang="+language_code;
        URL obj = new URL(url);
        HttpURLConnection httpConnection = (HttpURLConnection) obj.openConnection();
        httpConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1");
        httpConnection.setRequestMethod("POST");
        String urlParameters = "developer_trans_id=%developer_trans_id%&amount=%amount%&bank_id=%bank_id%"
                        +((success_url == null ||success_url.isEmpty())?"":"&success_url=%success_url%")
                        +((error_url == null ||error_url.isEmpty())?"":"&error_url=%error_url%")
                        +((state == null ||state.isEmpty())?"":"&state=%state%")
                        +((target == null ||target.isEmpty())?"":"&target=%target%");
        urlParameters = urlParameters.replaceFirst("%amount%", String.valueOf(amount));
        urlParameters = urlParameters.replaceFirst("%bank_id%", String.valueOf(bank_id));
        if(success_url != null && !success_url.isEmpty()){
            //success_url is optional
            urlParameters = urlParameters.replaceFirst("%success_url%", success_url);
        }
        if(error_url != null && !error_url.isEmpty()){
            //error_url is optional
            urlParameters = urlParameters.replaceFirst("%error_url%", error_url);
        }
        if(target != null && !target.isEmpty()){
            //target is optional
            urlParameters = urlParameters.replaceFirst("%state%", state);
        }
        if(target != null && !target.isEmpty()){
            //target is optional
            urlParameters = urlParameters.replaceFirst("%target%", target);
        }

        httpConnection.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(httpConnection.getOutputStream());
        wr.writeBytes(urlParameters);
        wr.flush();
        wr.close();

        onReceiveResponse(url, httpConnection, urlParameters);  
    }

    private void onReceiveResponse(String url, HttpURLConnection httpConnection, String urlParameters)
        throws IOException, UnsupportedEncodingException {
        int responseCode = httpConnection.getResponseCode();
        System.out.println("Url : " + url);
        System.out.println("Parameters : " + urlParameters);
        System.out.println("Response Code : " + responseCode);
        BufferedReader in = new BufferedReader(new InputStreamReader(httpConnection.getInputStream(),"UTF-8"));
        String inputLine;
        StringBuffer response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        String json = response.toString();
        System.out.println(json);
    }
	
    private static void disableSslVerification() {
        try
        {
            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(
                    java.security.cert.X509Certificate[] arg0, String arg1)
                    throws CertificateException {
                    }
                    public void checkServerTrusted(
                        java.security.cert.X509Certificate[] arg0, String arg1)
                        throws CertificateException {
                    }
            }
        };

        // Install the all-trusting trust manager
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {

            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        };

        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
    }
}
                                                                                                                                        
class AppotaPay
{
    private $API_URL = 'https://api.appotapay.com/';
    private $API_KEY;
    private $SECRET_KEY;
    private $LANG;
    private $VERSION = 'v1';
    private $METHOD = 'POST';

    public function __construct($config)
    {
        // set params
        $this->API_KEY = $config['api_key'];
        $this->LANG = $config['lang'];
        $this->SECRET_KEY = $config['secret_key'];
    }

    /*
    * function get payment bank url
    */
    public function getPaymentBankUrl($developer_trans_id, $amount, $client_ip, $state = '', $target = '', $success_url = '', $error_url = '', $bank_id = 0)
    {
        // build api url
        $api_url = $this->API_URL.$this->VERSION.'/services/ibanking?api_key='.$this->API_KEY.'&lang='.$this->LANG;
        // build params
        $params = array(
            'developer_trans_id' => $developer_trans_id, // Require param
            'amount' => $amount, // Require param
            'state'=> $state, // Optional param
            'target' => $target, // Optional param
            'success_url' => $success_url, // Optional param
            'error_url'=> $error_url, // Optional param
            'bank_id' => $bank_id, // Optional param
            'client_ip' => $client_ip // Require param
        );

        // request get payment url
        $result = $this->makeRequest($api_url, $params, $this->METHOD);
        // decode result
        $result = json_decode($result);

        // check result 
        if (isset($result->error_code) && $result->error_code === 0) { // charging success
            $transaction_id = $result->data->transaction_id;
            $bank_options = $result->data->bank_options;
            return $bank_options[0]->url;
        }
    }

    /*
    * function verify hash IPN for bank transaction
    * @param: pass your var $_POST that your server received from AppotaPay's server
    */
    public function verifyBankTransactionIpnHash($params)
    {
        // get params
        $status = $params['status'];
        $amount = $params['amount'];
        $type = $params['type'];
        $country_code = $params['country_code'];
        $currency = $params['currency'];
        $sandbox = $params['sandbox'];
        $state = $params['state'];
        $target = $params['target'];
        $transaction_id = $params['transaction_id'];
        $developer_trans_id = $params['developer_trans_id'];
        $transaction_type = $params['transaction_type'];
        $hash = $params['hash'];

        // check hash
        $check_hash = md5($amount . $country_code . $currency . $developer_trans_id . $sandbox . $state . $status . $target . $transaction_id . $transaction_type . $type . $this->SECRET_KEY);
        if ($check_hash !== $hash) {
            // return check hash fail
        }

        // check transaction status
        if ($status === 1) {
            // return transaction success 
            return array(
                    'error_code' => 0,
                    'amount' => $amount
            );
        } else {
            return array(
                    'error_code' => 1,
                    'amount' => 0
            );
        }
    }

    /*
    * function check transantion status
    * @param: developer_trans_id
    */
    public function checkTransaction($developer_trans_id)
    {
        // build api url
        $api_url = $this->API_URL.$this->VERSION.'/services/check_transaction_status?api_key='.$this->API_KEY.'&lang='.$this->LANG;
        // build params
        $params = array(
            'developer_trans_id' => $developer_trans_id,
            'transaction_type' => 'BANK'
        );

        // request check transaction
        $result = $this->makeRequest($api_url, $params, $this->METHOD);
        // decode result
        $result = json_decode($result);

        // check result 
        if (isset($result->error_code) && $result->error_code === 0) { // transaction success
            $transaction_id = $result->data->transaction_id; // appota transaction id
            $developer_trans_id = $result->data->developer_trans_id; // developer transaction id
            $amount = $result->data->amount;

        } else { // trasaction fail 
            return array(
                'error_code' => $result->error_code,
                'message' => $result->message
            );
        }
    }

    /*
     * function make request
     * url : string | url request
     * params : array | params request
     * method : string(POST,GET) | method request
     */
    private function makeRequest($url, $params, $method = 'POST')
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); // Time out 60s
        curl_setopt($ch, CURLOPT_TIMEOUT, 60); // connect time out 5s

        $result = curl_exec($ch);
        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if (curl_error($ch)) {
            return false;
        }
        
        if ($status != 200) {
            curl_close($ch);
            return false;
        }
        // close curl
        curl_close($ch);
        
        return $result;
    }
	
}                                                                                                                                        
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace AppotaPay.Model
{
    public static class BankPayment
    {
        public static string API_BANKPAYMENT = "https://api.appotapay.com/v1/services/ibanking?api_key=YOUR_API_KEY&lang=(vi | en)";

        public static async void getBankPayment(string developer_trans_id, int bank_id, string amount, string state, string target, string success_url, string error_url, string client_ip)
        {
            // developer_trans_id : ma giao dich phia doi tac
            // bank_id : id cua ngan hang (optional)
            // amount : Số tiền thanh toán (require)
            // state : Thông tin tuỳ chọn, không quá 150 ký tự (optional)
            // target : Thông tin tuỳ chọn, không quá 150 ký tự (optional)
            // success_url : Đường link sẽ được redirect tới nếu giao dịch thành công (optional)
            // error_url : Đường link sẽ được redirect tới nếu giao dịch thất bại (optional)
            // client_ip : IP client
            try
            {
                string data = "developer_trans_id=" + developer_trans_id + "&bank_id=" + bank_id + "&amount=" + amount + "&state=" + state + "&target=" + target + "&success_url=" + success_url + "&error_url=" + error_url + "&client_ip=" + client_ip;
                var returndata = await RequestAsync.SendPOSTData(API_BANKPAYMENT, data);
                Debug.WriteLine(returndata.ToString());
            }
            catch (Exception e) { }
        }
    }

    public class RequestAsync
    {
        public static Task GetResponseAsync(HttpWebRequest request)
        {
            var taskComplete = new TaskCompletionSource();
            request.BeginGetResponse(asyncResponse =>
            {
                try
                {
                    HttpWebRequest responseRequest = (HttpWebRequest)asyncResponse.AsyncState;
                    HttpWebResponse someResponse = (HttpWebResponse)responseRequest.EndGetResponse(asyncResponse);
                    taskComplete.TrySetResult(someResponse);
                }
                catch (WebException webExc)
                {
                    HttpWebResponse failedResponse = (HttpWebResponse)webExc.Response;
                    taskComplete.TrySetResult(failedResponse);
                }
            }, request);
            return taskComplete.Task;
        }

        public static async Task SendGETData(string urlToCall)
        {
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(urlToCall);
            httpWebRequest.Method = "GET";
            httpWebRequest.Accept = "application/json;odata=verbose";

            try
            {
                HttpWebResponse response = await GetResponseAsync(httpWebRequest);
                string ContentEncoding = response.Headers["Content-Encoding"];
                Stream responseStream = response.GetResponseStream();
                if (ContentEncoding == "gzip")
                {
                    responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                }

                string data;
                using (var reader = new System.IO.StreamReader(responseStream))
                {
                    data = reader.ReadToEnd();
                }

                return data;
            }
            catch
            {
                return "";
            }
        }

        public static async Task SendPOSTData(string urlToCall, string _data)
        {
            string url = urlToCall;

            var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
            httpWebRequest.ContentType = "application/x-www-form-urlencoded";
            httpWebRequest.Method = "POST";

            using (var stream = await Task.Factory.FromAsync(httpWebRequest.BeginGetRequestStream, httpWebRequest.EndGetRequestStream, null))
            {
                string data = _data;
                byte[] jsonAsBytes = Encoding.UTF8.GetBytes(data);
                await stream.WriteAsync(jsonAsBytes, 0, jsonAsBytes.Length);
            }

            var factory = new TaskFactory();
            var task = factory.FromAsync(httpWebRequest.BeginGetResponse, httpWebRequest.EndGetResponse, null);
            var response = await task;
            string ContentEncoding = response.Headers["Content-Encoding"];
            Stream responseStream = response.GetResponseStream();
            if (ContentEncoding == "gzip")
            {
                responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
            }

            StreamReader requestReader = new StreamReader(responseStream);
            string webResponse = requestReader.ReadToEnd();

            return webResponse;
        }

    }
}                                                                                                                
# -*- coding: utf-8 -*-
import requests ,json, sys

def get_payment_bank_url(amount):
    # set your application info
    api_key = 'A180026-KWXG1B-6E1F78892AACE00C'
    lang = 'vi'

    payload = {"developer_trans_id": "abc123456", "amount": amount}
    url = 'http://api.appotapay.com/v1/services/ibanking?api_key='+api_key+'&lang='+lang
    r = requests.post(url, data=payload)
    data = json.loads(r.content)
    print data

try:
    get_payment_bank_url(sys.argv[1])
except:
    print 'Invalid url'                                                  
                                                
POST:
{{http_code}}
                                        {{data_res}}
                                    
Document > Visa / Credit Card charging

Visa / Credit Card charging

Card Charging


Step 1: Client call to Payota’s API to get payment information. The information is returned link to payment site.

Step 2: Client conduct payment on payment site of Bank side.

Step 3: After Client sent payment requirement, Payota get payment information from provider , and calling to IPN url of Developer (which has been config during making application). After all, Developer will conduct to topup items, services, coin for client.

Step 4: Developer close payment window, then call to API to check transaction, showing notification on Client and finishing transaction.

Description

API Endpoint:
https://api.appotapay.com/v1/services/pay_visa?api_key=YOUR_API_KEY&lang=(vi | en)

Sandbox API Endpoint:
https://api.appotapay.com/v1/sandbox/services/pay_visa?api_key=YOUR_API_KEY&lang=(vi | en)

Method:
HTTP POST

Parametter List

Parametters

Require

main.desciption

Type

developer_trans_id

Yes

Developer's transaction ID (length limit is 5 to 30 characters)

String

amount

Yes

Money amount to charge

String

client_ip

Yes

IP address of user

String

state

No

Contents option, Length limit is less than 150 characters

String

target

No

Contents option, Length limit is less than 150 characters

String

success_url

No

Link will be redirect when transaction success

String

error_url

No

Link will be redirect when transaction fail

String

Response data

Name

Description

Type

error_code

Detail error code

Integer

data

Transaction detail

Object

data.transaction_id

main.transaction_id_des

String

data.developer_trans_id

Developer's transaction ID (length limit is 5 to 30 characters)

String

data.amount

Money amount to charge

String

data.currency

Currency unit

String

data.bank_options

Banking payment provider list

Array

data.bank_options.bank

Name of provider

String

data.bank_options.url

Link to payment site

String

message

Transaction note

String

Error Code Board

Error code

Detail

0

Call API successful

1

POST parameters to API is incorrect or error

5

Application is banned or not exists

7

Transaction not exist

11

The system is not support for this card

12

Card format incorrect

13

Developer account is banned or not exists

14

Amount is invalid, must greater than or equal to 10000

15

Transaction ID invalid!

16

Duplicate Transaction ID!

19

Users unrealized transactions

40

Server maintaining, Please try later

41

Transaction are waiting for treatment

91

System error, Please try later

INSTANT PAYMENT NOTIFICATION (IPN) URL

Method:
HTTP POST

Timeout:
10s

Parametter List

Parametters Description Type

status

Transaction status:
1. Successful transaction
0. Failed transaction

Integer

sandbox

1. Test transaction
0. Real trasaction

Integer

transaction_id

Transaction ID

String

developer_trans_id

Partner's transaction ID

String

transaction_type

Transaction type

String

amount

facevalue of transaction

String

currency

Currency unit

String

country_code

Country code

String

state

Value of `state` sent by API

String

target

Value of `target` sent by API

String

type

Transaction Type (ATM | VISA)

String

hash

Hash code security is called by Appota system to confirm IPN

hash = md5(amount + country_code + currency + developer_trans_id + sandbox + state + status + target + transaction_id + transaction_type + type + secret_key)

Connection string parameter values arranged in order from   (a -> z)

String

Response:
success: http code = 200, body {“error_code”: 0, “message”: “OK”}

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
	
public class BankPayment {

    public static final String BANK_PAYMENT_URL = "http://api.appotapay.com/v1/services/pay_visa?api_key=";

    public static void main(String[] args) {

            disableSslVerification(); //Enable disableSslVerification function just for testing

            int amount = 50000;//payment amount - VNĐ
            int bank_id = 10;//Bank id = 10 just for testing
            String developer_trans_id = ""; // Set your transaction id
            String apiKey = "your_api_key";
            String success_url = "";//optional - link to redirect to when make payment successfully
            String error_url = "";//optional - link to redirect to if make payment failed
            String state = "my state value";//optional - max 150 characters
            String target = "my target value";//optional - max 150 characters
            String languageCode = "vi";

            BankPayment payConnect = new BankPayment();

            try {
                    payConnect.makeBankPayment(apiKey, developer_trans_id, amount, bank_id, success_url, error_url, state, target, languageCode);
            } catch (Exception e) {
                    e.printStackTrace();
            }
    }

    private  void makeBankPayment(String api_key, String developer_trans_id, int amount,int bank_id,String success_url, String error_url,
        String state, String target,String language_code) throws Exception {

        String url = BANK_PAYMENT_URL +api_key+"&lang="+language_code;
        URL obj = new URL(url);
        HttpURLConnection httpConnection = (HttpURLConnection) obj.openConnection();
        httpConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1");
        httpConnection.setRequestMethod("POST");
        String urlParameters = "developer_trans_id=%developer_trans_id%&amount=%amount%&bank_id=%bank_id%"
                        +((success_url == null ||success_url.isEmpty())?"":"&success_url=%success_url%")
                        +((error_url == null ||error_url.isEmpty())?"":"&error_url=%error_url%")
                        +((state == null ||state.isEmpty())?"":"&state=%state%")
                        +((target == null ||target.isEmpty())?"":"&target=%target%");
        urlParameters = urlParameters.replaceFirst("%amount%", String.valueOf(amount));
        urlParameters = urlParameters.replaceFirst("%bank_id%", String.valueOf(bank_id));
        if(success_url != null && !success_url.isEmpty()){
            //success_url is optional
            urlParameters = urlParameters.replaceFirst("%success_url%", success_url);
        }
        if(error_url != null && !error_url.isEmpty()){
            //error_url is optional
            urlParameters = urlParameters.replaceFirst("%error_url%", error_url);
        }
        if(target != null && !target.isEmpty()){
            //target is optional
            urlParameters = urlParameters.replaceFirst("%state%", state);
        }
        if(target != null && !target.isEmpty()){
            //target is optional
            urlParameters = urlParameters.replaceFirst("%target%", target);
        }

        httpConnection.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(httpConnection.getOutputStream());
        wr.writeBytes(urlParameters);
        wr.flush();
        wr.close();

        onReceiveResponse(url, httpConnection, urlParameters);  
    }

    private void onReceiveResponse(String url, HttpURLConnection httpConnection, String urlParameters)
        throws IOException, UnsupportedEncodingException {
        int responseCode = httpConnection.getResponseCode();
        System.out.println("Url : " + url);
        System.out.println("Parameters : " + urlParameters);
        System.out.println("Response Code : " + responseCode);
        BufferedReader in = new BufferedReader(new InputStreamReader(httpConnection.getInputStream(),"UTF-8"));
        String inputLine;
        StringBuffer response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        String json = response.toString();
        System.out.println(json);
    }
	
    private static void disableSslVerification() {
        try
        {
            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(
                    java.security.cert.X509Certificate[] arg0, String arg1)
                    throws CertificateException {
                    }
                    public void checkServerTrusted(
                        java.security.cert.X509Certificate[] arg0, String arg1)
                        throws CertificateException {
                    }
            }
        };

        // Install the all-trusting trust manager
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {

            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        };

        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
    }
}                                                                                                                                        
class AppotaPay
{
    private $API_URL = 'https://api.appotapay.com/';
    private $API_KEY;
    private $SECRET_KEY;
    private $LANG;
    private $VERSION = 'v1';
    private $METHOD = 'POST';

    public function __construct($config)
    {
        // set params
        $this->API_KEY = $config['api_key'];
        $this->LANG = $config['lang'];
        $this->SECRET_KEY = $config['secret_key'];
    }

    /*
    * function get payment bank url
    */
    public function getPaymentBankUrl($developer_trans_id, $amount, $client_ip, $state = '', $target = '', $success_url = '', $error_url = '', $bank_id = 0)
    {
        // build api url
        $api_url = $this->API_URL.$this->VERSION.'/services/pay_visa?api_key='.$this->API_KEY.'&lang='.$this->LANG;
        // build params
        $params = array(
            'developer_trans_id' => $developer_trans_id, // Require param
            'amount' => $amount, // Require param
            'state'=> $state, // Optional param
            'target' => $target, // Optional param
            'success_url' => $success_url, // Optional param
            'error_url'=> $error_url, // Optional param
            'bank_id' => $bank_id, // Optional param
            'client_ip' => $client_ip // Require param
        );

        // request get payment url
        $result = $this->makeRequest($api_url, $params, $this->METHOD);
        // decode result
        $result = json_decode($result);

        // check result 
        if (isset($result->error_code) && $result->error_code === 0) { // charging success
            $transaction_id = $result->data->transaction_id;
            $bank_options = $result->data->bank_options;
            return $bank_options[0]->url;
        }
    }

    /*
    * function verify hash IPN for bank transaction
    * @param: pass your var $_POST that your server received from AppotaPay's server
    */
    public function verifyBankTransactionIpnHash($params)
    {
        // get params
        $status = $params['status'];
        $amount = $params['amount'];
        $type = $params['type'];
        $country_code = $params['country_code'];
        $currency = $params['currency'];
        $sandbox = $params['sandbox'];
        $state = $params['state'];
        $target = $params['target'];
        $transaction_id = $params['transaction_id'];
        $developer_trans_id = $params['developer_trans_id'];
        $transaction_type = $params['transaction_type'];
        $hash = $params['hash'];

        // check hash
        $check_hash = md5($amount . $country_code . $currency . $developer_trans_id . $sandbox . $state . $status . $target . $transaction_id . $transaction_type . $type . $this->SECRET_KEY);
        if ($check_hash !== $hash) {
            // return check hash fail
        }

        // check transaction status
        if ($status === 1) {
            // return transaction success 
            return array(
                    'error_code' => 0,
                    'amount' => $amount
            );
        } else {
            return array(
                    'error_code' => 1,
                    'amount' => 0
            );
        }
    }

    /*
    * function check transantion status
    * @param: transaction_id
    */
    public function checkTransaction($developer_trans_id)
    {
        // build api url
        $api_url = $this->API_URL.$this->VERSION.'/services/check_transaction_status?api_key='.$this->API_KEY.'&lang='.$this->LANG;
        // build params
        $params = array(
            'developer_trans_id' => $transaction_id,
            'transaction_type' => 'BANK'
        );

        // request check transaction
        $result = $this->makeRequest($api_url, $params, $this->METHOD);
        // decode result
        $result = json_decode($result);

        // check result 
        if (isset($result->error_code) && $result->error_code === 0) { // transaction success
            $transaction_id = $result->data->transaction_id; // appota transaction id
            $developer_trans_id = $result->data->developer_trans_id; // developer transaction id
            $amount = $result->data->amount;

        } else { // trasaction fail 
            return array(
                'error_code' => $result->error_code,
                'message' => $result->message
            );
        }
    }

    /*
     * function make request
     * url : string | url request
     * params : array | params request
     * method : string(POST,GET) | method request
     */
    private function makeRequest($url, $params, $method = 'POST')
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); // Time out 60s
        curl_setopt($ch, CURLOPT_TIMEOUT, 60); // connect time out 5s

        $result = curl_exec($ch);
        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if (curl_error($ch)) {
            return false;
        }
        
        if ($status != 200) {
            curl_close($ch);
            return false;
        }
        // close curl
        curl_close($ch);
        
        return $result;
    }
	
}                                                                                                                                        
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace AppotaPay.Model
{
    public static class BankPayment
    {
        public static string API_BANKPAYMENT = "https://api.appotapay.com/v1/services/pay_visa?api_key=YOUR_API_KEY&lang=(vi | en)";

        public static async void getBankPayment(string developer_trans_id, int bank_id, string amount, string state, string target, string success_url, string error_url, string client_ip)
        {
            // developer_trans_id : ma giao dich phia doi tac
            // bank_id : id cua ngan hang (optional)
            // amount : Số tiền thanh toán (require)
            // state : Thông tin tuỳ chọn, không quá 150 ký tự (optional)
            // target : Thông tin tuỳ chọn, không quá 150 ký tự (optional)
            // success_url : Đường link sẽ được redirect tới nếu giao dịch thành công (optional)
            // error_url : Đường link sẽ được redirect tới nếu giao dịch thất bại (optional)
            // client_ip : IP client
            try
            {
                string data = "developer_trans_id=" + developer_trans_id + "&bank_id=" + bank_id + "&amount=" + amount + "&state=" + state + "&target=" + target + "&success_url=" + success_url + "&error_url=" + error_url + "&client_ip=" + client_ip;
                var returndata = await RequestAsync.SendPOSTData(API_BANKPAYMENT, data);
                Debug.WriteLine(returndata.ToString());
            }
            catch (Exception e) { }
        }
    }

    public class RequestAsync
    {
        public static Task GetResponseAsync(HttpWebRequest request)
        {
            var taskComplete = new TaskCompletionSource();
            request.BeginGetResponse(asyncResponse =>
            {
                try
                {
                    HttpWebRequest responseRequest = (HttpWebRequest)asyncResponse.AsyncState;
                    HttpWebResponse someResponse = (HttpWebResponse)responseRequest.EndGetResponse(asyncResponse);
                    taskComplete.TrySetResult(someResponse);
                }
                catch (WebException webExc)
                {
                    HttpWebResponse failedResponse = (HttpWebResponse)webExc.Response;
                    taskComplete.TrySetResult(failedResponse);
                }
            }, request);
            return taskComplete.Task;
        }

        public static async Task SendGETData(string urlToCall)
        {
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(urlToCall);
            httpWebRequest.Method = "GET";
            httpWebRequest.Accept = "application/json;odata=verbose";

            try
            {
                HttpWebResponse response = await GetResponseAsync(httpWebRequest);
                string ContentEncoding = response.Headers["Content-Encoding"];
                Stream responseStream = response.GetResponseStream();
                if (ContentEncoding == "gzip")
                {
                    responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                }

                string data;
                using (var reader = new System.IO.StreamReader(responseStream))
                {
                    data = reader.ReadToEnd();
                }

                return data;
            }
            catch
            {
                return "";
            }
        }

        public static async Task SendPOSTData(string urlToCall, string _data)
        {
            string url = urlToCall;

            var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
            httpWebRequest.ContentType = "application/x-www-form-urlencoded";
            httpWebRequest.Method = "POST";

            using (var stream = await Task.Factory.FromAsync(httpWebRequest.BeginGetRequestStream, httpWebRequest.EndGetRequestStream, null))
            {
                string data = _data;
                byte[] jsonAsBytes = Encoding.UTF8.GetBytes(data);
                await stream.WriteAsync(jsonAsBytes, 0, jsonAsBytes.Length);
            }

            var factory = new TaskFactory();
            var task = factory.FromAsync(httpWebRequest.BeginGetResponse, httpWebRequest.EndGetResponse, null);
            var response = await task;
            string ContentEncoding = response.Headers["Content-Encoding"];
            Stream responseStream = response.GetResponseStream();
            if (ContentEncoding == "gzip")
            {
                responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
            }

            StreamReader requestReader = new StreamReader(responseStream);
            string webResponse = requestReader.ReadToEnd();

            return webResponse;
        }

    }
}
                                                                                                                
# -*- coding: utf-8 -*-
import requests ,json, sys

def get_payment_bank_url(amount):
    # set your application info
    api_key = 'A180026-KWXG1B-6E1F78892AACE00C'
    lang = 'vi'

    payload = {"developer_trans_id": "abc123456", "amount": amount}
    url = 'http://api.appotapay.com/v1/services/pay_visa?api_key='+api_key+'&lang='+lang
    r = requests.post(url, data=payload)
    data = json.loads(r.content)
    print data

try:
    get_payment_bank_url(sys.argv[1])
except:
    print 'Invalid url'                                                  
                                                
POST:
{{http_code}}
                                        {{data_res}}
                                    
Document > Card Charging

Card Charging

Conection model


Step 1: Developer gather scratch card information from client (Serial number, Code number, card type)

Step 2: Developer conduct POST parameters to API of Appota Pay.

Step 3: Appota Pay conduct to charge scratch card via Telco’s confirmation before send resuit to client, and calling to IPN url of Developer (which has been config during making application) at the same time. After all, Developer will conduct to topup items, services, coin for client.

Step 4: Sending notification with successful transaction to client and finish transaction.

Description

API Endpoint:
https://api.appotapay.com/v1/services/card_charging?api_key=YOUR_API_KEY&lang=(vi | en)

Sandbox API Endpoint:
https://api.appotapay.com/v1/sandbox/services/card_charging?api_key=YOUR_API_KEY&lang=(vi | en)

Method:
HTTP POST

Parametter List

Parametters

Require

main.desciption

Type

developer_trans_id

Yes

Developer's transaction ID (length limit is 5 to 30 characters)

String

card_code

Yes

Code number

String

card_serial

Yes

Serial number

String

vendor

Yes

Card Providers (viettel, vinaphone, mobifone, fpt, mega, vtc, appota)

String

state

No

Contents option, Length limit is less than 150 characters

String

target

No

Contents option, Length limit is less than 150 characters

String

Response data

Name

Description

Type

error_code

Detail error code

Integer

data

Transaction detail

Object

data.transaction_id

main.transaction_id_des

String

data.developer_trans_id

Developer's transaction ID (length limit is 5 to 30 characters)

String

data.currency

Currency unit

String

data.country_code

Country code

Array

data.time

Transaction time

String

data.sandbox

Transaction status (1. Test transaction, 0. Real trasaction)

Integer

message

Transaction note

String

data_signature

Data signature

String

Error Code Board

Error code

Detail

0

Call API successful

1

POST parameters to API is incorrect or error

5

Application is banned or not exists

7

Transaction not exist

11

The system is not support for this card

12

Card format incorrect

13

Developer account is banned or not exists

15

Transaction ID invalid!

16

Duplicate Transaction ID!

38

The phone card has been locked, please come back in 1 hour

39

Card code has been used or not exists

40

Server maintaining, Please try later

41

Transaction are waiting for treatment

91

System error, Please try later

INSTANT PAYMENT NOTIFICATION (IPN) URL

Method:
HTTP POST

Timeout:
10s

Parametter List

Parametters Description Type

status

Transaction status:
1. Successful transaction
0. Failed transaction

Integer

sandbox

1. Test transaction
0. Real trasaction

Integer

transaction_id

Transaction ID

String

developer_trans_id

Partner's transaction ID

String

transaction_type

Transaction type

String

card_code

Code number<

String

card_serial

Serial thẻ

Serial number

card_vendor

Card Providers

String

amount

The facevalue of card

String

currency

Currency unit

String

country_code

Country code

String

state

Value of `state` sent by API

String

target

Value of `target` sent by API

String

hash

Hash code security is called by Appota system to confirm IPN

hash = md5(amount + card_code + card_serial + card_vendor + country_code + currency + developer_trans_id + sandbox + state + status + target + transaction_id + transaction_type + secret_key)

Connection string parameter values arranged in order from   (a -> z)

String

Response:
success: http code = 200, body {“error_code”: 0, “message”: “OK”}

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
	
public class CardPayment {

    public static final String CARD_PAYMENT_URL = "https://api.appotapay.com/v1/services/card_charging?api_key=";

    public static void main(String[] args) {

        String apiKey = "your_api_key";
        String developerTransId = "Your transaction id";
        String cardCode = "card_code_value";
        String cardSerial = "card_serial_value";
        String vendor = "vendor";//ex: viettel,vinaphone..
        String state = "my state value";//optional - max 150 characters
        String target = "my target value";//optional - max 150 characters
        String languageCode = "vi";

        CardPayment payConnect = new CardPayment();

        disableSslVerification(); //Enable disableSslVerification function just for testing

        try {
            payConnect.makeCardPayment(apiKey, developerTransId, cardCode, cardSerial, vendor, state, target, languageCode);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private  void makeCardPayment(String api_key, String developer_trans_id, String card_code, String card_serial, String vendor,String state, String target,String language_code) throws Exception {
        String url = CARD_PAYMENT_URL +api_key+"&lang="+language_code;
        URL obj = new URL(url);
        HttpURLConnection httpConnection = (HttpURLConnection) obj.openConnection();
        httpConnection.setRequestMethod("POST");
        String urlParameters = "developer_trans_id=%developer_trans_id%&card_code=%card_code%&card_serial=%card_serial%&vendor=%vendor%"+((state == null ||state.isEmpty())?"":"&state=%state%")+((target == null ||target.isEmpty())?"":"&target=%target%");
        urlParameters = urlParameters.replaceFirst("%developer_trans_id%", developer_trans_id);
        urlParameters = urlParameters.replaceFirst("%card_code%", card_code);
        urlParameters = urlParameters.replaceFirst("%card_serial%", card_serial);
        urlParameters = urlParameters.replaceFirst("%vendor%", vendor);
        if(target != null && !target.isEmpty()){
            //target is optional
            urlParameters = urlParameters.replaceFirst("%state%", state);
        }
        if(target != null && !target.isEmpty()){
            //target is optional
            urlParameters = urlParameters.replaceFirst("%target%", target);
        }

        httpConnection.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(httpConnection.getOutputStream());
        wr.writeBytes(urlParameters);
        wr.flush();
        wr.close();

        onReceiveResponse(url, httpConnection, urlParameters);  
    }

    private void onReceiveResponse(String url, HttpURLConnection httpConnection, String urlParameters)throws IOException, UnsupportedEncodingException {
        int responseCode = httpConnection.getResponseCode();
        System.out.println("URL : " + url);
        System.out.println("Parameters : " + urlParameters);
        System.out.println("Response Code : " + responseCode);
        BufferedReader in = new BufferedReader(new InputStreamReader(httpConnection.getInputStream(),"UTF-8"));
        String inputLine;
        StringBuffer response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        String json = response.toString();
        System.out.println(json);
    }

    private static void disableSslVerification() {
        try
        {
            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(
                    java.security.cert.X509Certificate[] arg0, String arg1)
                    throws CertificateException {
                    }
                public void checkServerTrusted(
                    java.security.cert.X509Certificate[] arg0, String arg1)
                    throws CertificateException {
                }
            }
            };

            // Install the all-trusting trust manager
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            // Create all-trusting host name verifier
            HostnameVerifier allHostsValid = new HostnameVerifier() {

                public boolean verify(String arg0, SSLSession arg1) {
                        return true;
                }
            };

            // Install the all-trusting host verifier
            HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
    }

}
                                                                                                                                       
class AppotaPay
{
    private $API_URL = 'https://api.appotapay.com/';
    private $API_KEY;
    private $SECRET_KEY;
    private $LANG;
    private $VERSION = 'v1';
    private $METHOD = 'POST';

    public function __construct($config)
    {
        // set params
        $this->API_KEY = $config['api_key'];
        $this->LANG = $config['lang'];
        $this->SECRET_KEY = $config['secret_key'];
    }

    /*
    * function card charging
    */
    public function cardCharging($developer_trans_id, $code, $serial, $vendor, $state, $target)
    {
        // build api url
        $api_url = $this->API_URL.$this->VERSION.'/services/card_charging?api_key='.$this->API_KEY.'&lang='.$this->LANG;
        // build params
        $params = array(
            'developer_trans_id' => $developer_trans_id,
            'card_code' => $code,
            'card_serial' => $serial,
            'vendor' => $vendor,
            'state' => $state, // Optional param
            'target' => $target // Optional param
        );

        // request charging
        $result = $this->makeRequest($api_url, $params, $this->METHOD);
        // decode result
        $result = json_decode($result);

        // check result 
        if (isset($result->error_code) && $result->error_code === 0) { // charging success
           return array(
             'success' => true,
             'amount' => $result->data->amount,
             'transaction_id' => $result->data->transaction_id
           );
        } else {
            return array(
             'success' => false,
             'error_code' => $result->error_code,
             'message' => $result->message
           );
         }
    }

    /*
    * function check transantion status
    * @param: developer_trans_id
    */
    public function checkTransaction($developer_trans_id)
    {
        // build api url
        $api_url = $this->API_URL.$this->VERSION.'/services/check_transaction_status?api_key='.$this->API_KEY.'&lang='.$this->LANG;
        // build params
        $params = array(
            'developer_trans_id' => $developer_trans_id,
            'transaction_type' => 'CARD'
        );

        // request check transaction
        $result = $this->makeRequest($api_url, $params, $this->METHOD);
        // decode result
        $result = json_decode($result);

        // check result 
        if (isset($result->error_code) && $result->error_code === 0) { // transaction success
            $transaction_id = $result->data->transaction_id;
            $developer_trans_id = $result->data->developer_trans_id;
            $amount = $result->data->amount;
        } else { // trasaction fail 
            return array(
                    'error_code' => $result->error_code,
                    'message' => $result->message
            );
        }
    }

    /*
    * function verify hash IPN for card transaction
    * @param: pass your var $_POST that your server received from AppotaPay's server
    */
    public function verifyCardTransactionIpnHash($params)
    {
        // get params
        $status = $params['status'];
        $amount = $params['amount'];
        $card_code = $params['card_code'];
        $card_serial = $params['card_serial'];
        $vendor = $params['card_vendor'];
        $country_code = $params['country_code'];
        $currency = $params['currency'];
        $sandbox = $params['sandbox'];
        $state = $params['state'];
        $target = $params['target'];
        $transaction_id = $params['transaction_id'];
        $developer_trans_id = $params['developer_trans_id'];
        $transaction_type = $params['transaction_type'];
        $hash = $params['hash'];

        // check hash
        $check_hash = md5($amount . $card_code . $card_serial . $vendor . $country_code . $currency . $developer_trans_id . $sandbox. $state . $status . $target . $transaction_id . $transaction_type . $this->SECRET_KEY);
        if ($check_hash !== $hash) {
            // return check hash fail
        }

        // check transaction status
        if ($status === 1) {
            // return transaction success 
            return array(
                    'error_code' => 0,
                    'amount' => $amount
            );
        } else {
            return array(
                    'error_code' => 1,
                    'amount' => 0
            );
        }
    }

    /*
     * function make request
     * url : string | url request
     * params : array | params request
     * method : string(POST,GET) | method request
     */
    private function makeRequest($url, $params, $method = 'POST')
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); // Time out 60s
        curl_setopt($ch, CURLOPT_TIMEOUT, 60); // connect time out 60s

        $result = curl_exec($ch);
        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if (curl_error($ch)) {
            return false;
        }
        
        if ($status != 200) {
            curl_close($ch);
            return false;
        }
        // close curl
        curl_close($ch);
        
        return $result;
    }
	
}                                                                                                                                        
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace AppotaPay.Models
{
    public static class CardPayment
    {
        public static string API_CARDPAYMENT = "https://api.appotapay.com/v1/services/card_charging?api_key=YOUR_API_KEY&lang=(vi | en)";

        public static async void getCardPayment(string card_code, string card_serial, string vendor, string state, string target)
        {
            // developer_trans_id : Mã giao dích phía đối tác (require)
            // card_code : Mã thẻ cào (require)
            // card_serial : Mã serial thẻ cào (require)
            // vendor : Nhà cung cấp (viettel, vinaphone, mobifone, fpt, mega, vtc, appota) (require)
            // state : Thông tin tuỳ chọn, không quá 150 ký tự (optional)
            // target : Thông tin tuỳ chọn, không quá 150 ký tự (optional)
            try
            {
                string data = "developer_trans_id=" + developer_trans_id + "&card_code=" + card_code + "&card_serial=" + card_serial + "&vendor=" + vendor + "&state=" + state + "&target=" + target;
                var returndata = await RequestAsync.SendPOSTData(API_CARDPAYMENT, data);
                Debug.WriteLine(returndata.ToString());
            }
            catch (Exception e) { }
        }
    }

    public class RequestAsync
    {
        public static Task GetResponseAsync(HttpWebRequest request)
        {
            var taskComplete = new TaskCompletionSource();
            request.BeginGetResponse(asyncResponse =>
            {
                try
                {
                    HttpWebRequest responseRequest = (HttpWebRequest)asyncResponse.AsyncState;
                    HttpWebResponse someResponse = (HttpWebResponse)responseRequest.EndGetResponse(asyncResponse);
                    taskComplete.TrySetResult(someResponse);
                }
                catch (WebException webExc)
                {
                    HttpWebResponse failedResponse = (HttpWebResponse)webExc.Response;
                    taskComplete.TrySetResult(failedResponse);
                }
            }, request);
            return taskComplete.Task;
        }

        public static async Task SendGETData(string urlToCall)
        {
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(urlToCall);
            httpWebRequest.Method = "GET";
            httpWebRequest.Accept = "application/json;odata=verbose";

            try
            {
                HttpWebResponse response = await GetResponseAsync(httpWebRequest);
                string ContentEncoding = response.Headers["Content-Encoding"];
                Stream responseStream = response.GetResponseStream();
                if (ContentEncoding == "gzip")
                {
                    responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                }

                string data;
                using (var reader = new System.IO.StreamReader(responseStream))
                {
                    data = reader.ReadToEnd();
                }

                return data;
            }
            catch
            {
                return "";
            }
        }


        public static async Task SendPOSTData(string urlToCall, string _data)
        {
            string url = urlToCall;

            var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
            httpWebRequest.ContentType = "application/x-www-form-urlencoded";
            httpWebRequest.Method = "POST";

            using (var stream = await Task.Factory.FromAsync(httpWebRequest.BeginGetRequestStream, httpWebRequest.EndGetRequestStream, null))
            {
                string data = _data;
                byte[] jsonAsBytes = Encoding.UTF8.GetBytes(data);
                await stream.WriteAsync(jsonAsBytes, 0, jsonAsBytes.Length);
            }

            var factory = new TaskFactory();
            var task = factory.FromAsync(httpWebRequest.BeginGetResponse, httpWebRequest.EndGetResponse, null);
            var response = await task;
            string ContentEncoding = response.Headers["Content-Encoding"];
            Stream responseStream = response.GetResponseStream();
            if (ContentEncoding == "gzip")
            {
                responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
            }

            StreamReader requestReader = new StreamReader(responseStream);
            string webResponse = requestReader.ReadToEnd();

            return webResponse;
        }

    }
}                                                                                                                
# -*- coding: utf-8 -*-
import requests ,json, sys

def card_charging(code, serial, vendor):
    # set your application info
    api_key = 'A180026-KWXG1B-6E1F78892AACE00C'
    lang = 'vi'

    payload = {"developer_trans_id": "developer_trans_id", "card_code": code, "card_serial": serial, "vendor": vendor}
    url = 'https://api.appotapay.com/v1/services/card_charging?api_key='+api_key+'&lang='+lang
    r = requests.post(url, data=payload)
    data = json.loads(r.content)
    print data

try:
    card_charging(sys.argv[1], sys.argv[2], sys.argv[3])
except:
    print 'Invalid url'                                                  
                                                
POST:
{{http_code}}
                                        {{data_res}}