AIRTIME INTEGRATION_Version3 (13)
AIRTIME INTEGRATION_Version3 (13)
AIRTIME INTEGRATION
Bujumbura, 06/2019
Mục lục
I. Pre-requirement.....................................................................................................................3
1. Supply to partner...............................................................................................................3
1.1 Link to connect...........................................................................................................3
1.2 API to check balance..................................................................................................6
1.3 API recharge money to customer...............................................................................7
1.4 API recharge money to customer with Batch of Customer........................................9
1.5 Decribe class TextSecurity.......................................................................................10
1.6 Describe Response of webservice API...........................................................................20
1.7. Template code for integration with these APIs..............................................................24
I. Pre-requirement
Partner must come BUJUMBURA Branch to make contract about Anypay Account and deposit money
Send these information: contract, Anypay Account, IP of server to set up VPN connection as below, to IT Team of Lumitel
o Partner must supply Lumitel
The IP of Partner System: IP of gateway, IP of Server to set up VPN connection as below
Account of Anypay, the contract
VPN Connection
Location Bujumbura
Tunnel
Lumitel Partner
Properties
Pre-Shared Key
Authentication
Method
Lumitel@123 Lumitel@123
Encryption
AES
Scheme
Diffie-
Hellman Group 2
Group
Encryption
AES-256
Algorithm
Hashing
SHA 1
Algorithm
Main or
Aggressive Main Mode (IKE v1 preferred)
Mode
Phase 2 IKE (Phase 1)
Lifetime (for
28800 seconds
renegotiation)
Pre-shared key
Encapsulation ESP
(ESP or AH)
Encryption
AES-256
Algorithm
Authentication
SHA 1
Algorithm
Perfect
Forward Disabled
Secrecy
Lifetime (for
N/A
renegotiation)
Lifesize in KB
(for N/A
renegotiation)
VPN Gateway
Lumitel Partner
Device Information
Ex:
Peer IP Address 154.73.104.100
41.79.226.30
VPN Device
FORTIGATE
Description
Location BUJUMBURA
Encryption
Domain/Servers 10.225.6.73
(Hosts to be http://10.225.6.73:8128/BCCSGateway?wsdl
encrypted)
Herein:
In data tag:
69061690 -> Your SIM ToolKit number, -> Lumitel will supply after you have contract
8925708000280002994 -> Your ICCID, -> Lumitel will supply after you have contract
4F3BEEE56B49348D-> Your PIN of SIM Toolkit -> Lumitel will supply after you have contract
Data item is with this format: SOURCE_MSISDN|ICCID|MPIN|TARGET_MSISDN|AMOUNT
o SOURCE_MSISDN -> your sim toolkit number (ex: 69061690) -> Lumitel will supply after you have contract
o TARGET_MSISDN -> your customer’s number who you want to recharge airtime for him (ex: 61000111)
o AMOUNT -> money in FBU, must be encrypted
Ex: BC28D222A9CCF03C -> 500 FBU
o 8925708000280002994 -> Your ICCID, -> Lumitel will supply after you have contract
o 4F3BEEE56B49348D-> Your PIN of SIM Toolkit -> Lumitel will supply after you have contract
Herein:
Code Template
Change name of file: PaywayWS Send Partner.rar_ChangeName to PaywayWS Send Partner.rar -> this is code template
package com.viettel.payway.ws.utils;
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.zip.Adler32;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import org.apache.log4j.Logger;
public class TextSecurity {
Adler32, CRC32
}
MD5, SHA
}
/**
* based on sun link
* https://java.sun.com/j2se/1.4.2/docs/guide/security/jce/JCERefGuide.html#AppA
* DESede is Tripple DES algorithm
*
* @author xakn1
*
*/
public enum EncryptionAlgorithm {
/**
*
* @param input
* @param alogorithm e.g MD5, SHA algorithms
*/
public void computeDigest(String input, MessageDigestAlgorithm alogorithm) {
msgdig.update(input.getBytes());
byte[] mdbytes = msgdig.digest();
}
/**
*
* @param input
* @param algorthm
* @return
*/
public long computeCheckSum(String input, CheckSumAlgorithm algorithm) {
long sum = -1;
Checksum cs = null;
if (algorithm.equals(CheckSumAlgorithm.Adler32)) {
cs = new Adler32();
} else if (algorithm.equals(CheckSumAlgorithm.CRC32)) {
cs = new CRC32();
}
cs.update(input.getBytes(), 0, input.length());
sum = cs.getValue();
return sum;
}
/**
* hexEncode is create String object which contains hex representation of
* data present in bytes array
*
* @param bytes - input array of bytes to be hex coded
* @return String objecting containing hex representation of bytes in input
* array
*/
public String hexEncode(byte[] bytes) {
StringBuilder buffer = new StringBuilder(bytes.length * 2);
for (int i = 0; i < bytes.length; i++) {
byte byteValue = bytes[i];
buffer.append(digits[(byteValue & 0xf0) >> 4]);
buffer.append(digits[byteValue & 0x0f]);
}
return buffer.toString();
}
/**
*
* @param clearText
* @param cipher
* @param secretKey
* @param ivVector Initialization Vector
* @return
* @throws PAPException
*/
public byte[] encrypt(String clearText, Cipher cipher, SecretKey secretKey, IvParameterSpec ivVector) {
/**
*
* @param cipherText
* @param cipher
* @param secretKey
* @param ivVector
* @return
* @throws PAPException
*/
public String decrypt(byte[] cipherText, Cipher cipher, SecretKey secretKey, IvParameterSpec ivVector) {
byte[] cleartext = null;
try {
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivVector);
cleartext = cipher.doFinal(cipherText);
} catch (Exception e) {
throw new RuntimeException(e);
}
return new String(cleartext);
}
public byte[] encryptPass2(String pass) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException,
NoSuchPaddingException {
computeDigest("SecretWord", MessageDigestAlgorithm.MD5);
computeDigest("SecretWord", MessageDigestAlgorithm.SHA);
computeCheckSum("SecretWord", CheckSumAlgorithm.Adler32);
computeCheckSum("SecretWord", CheckSumAlgorithm.CRC32);
//uses the first 24 bytes in the secret
// DESedeKeySpec keyspec = new DESedeKeySpec(secret.getBytes());
DESedeKeySpec keyspec
= new DESedeKeySpec(share_key.getBytes());
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance(EncryptionAlgorithm.DESede.name());
SecretKey deskey = keyfactory.generateSecret(keyspec);
computeCheckSum("SecretWord", CheckSumAlgorithm.Adler32);
computeCheckSum("SecretWord", CheckSumAlgorithm.CRC32);
return result;
}
return result;
}
private TextSecurity() {
String en = sec.Encrypt(str1);
System.out.println("'" + str1 + "' -> '" + en + "'");
String en2 = sec.Encrypt(str2);
System.out.println("'" + str2 + "' -> '" + en2 + "'");
String en3 = sec.Encrypt(str3);
System.out.println("'" + str3 + "' -> '" + en3 + "'");
String en4 = sec.Encrypt(str4);
System.out.println("'" + str4 + "' -> '" + en4 + "'");
}
}
1.6 Describe Response of webservice API
1.6.1 Result of authentication and connection to firewall layer of webservice
error description Example
0 success This is result of calling webservice:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:gwOperationResponse xmlns:ns2="http://webservice.bccsgw.viettel.com/">
<Result>
<error>0</error>
<description>success</description>
<return/>
<original><![CDATA[<?xml version="1.0" ?><S:Envelope
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:getAccountInfoResponse
xmlns:ns2="http://ws.payway.viettel.com/"><return><description>Successful</
description><responseCode>0000</responseCode><result><balance>31651011</balance></
result></return></ns2:getAccountInfoResponse></S:Body></S:Envelope>]]></original>
</Result>
</ns2:gwOperationResponse>
</S:Body>
</S:Envelope>
Other Fail This is result of calling webservice:
(6003,
2001…) <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:gwOperationResponse xmlns:ns2="http://webservice.bccsgw.viettel.com/">
<Result>
<error>6003</error>
<description>Login failed. Please check user name, password and your IP Address and
contact the administrator</description>
</Result>
</ns2:gwOperationResponse>
</S:Body>
</S:Envelope>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:gwOperationResponse xmlns:ns2="http://webservice.bccsgw.viettel.com/">
<Result>
<error>0</error>
<description>success</description>
<return/>
<original><![CDATA[<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body>
<ns2:getAccountInfoResponse xmlns:ns2="http://ws.payway.viettel.com/"><return>
<description>Successful</description>
<responseCode>0000</responseCode>
<result><balance>31651011</balance></result>
</return></ns2:getAccountInfoResponse></S:Body>
</S:Envelope>]]></original>
</Result>
</ns2:gwOperationResponse>
</S:Body>
</S:Envelope>
-5 Fail Source Msisdn is invalid
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:gwOperationResponse xmlns:ns2="http://webservice.bccsgw.viettel.com/">
<Result>
<error>0</error>
<description>success</description>
<return/>
<original><![CDATA[<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/
soap/envelope/"><S:Body>
<ns2:getAccountInfoResponse xmlns:ns2=
"http://ws.payway.viettel.com/">
<return><description>Msisdn invalid 61008422</description>
<responseCode>-5</responseCode>
</return></ns2:getAccountInfoResponse>
</S:Body></S:Envelope>]]></original>
</Result>
</ns2:gwOperationResponse>
</S:Body>
</S:Envelope>
-1 Fail Login information is not correct
<error>0</error
<description>Login information is not correct</description><responseCode>-1</responseCode>
1 Fail Target Msisdn invalid
<error>0</error
<description>Msisdn invalid 824857 </description><responseCode>1</responseCode>
3 Fail <error>0</error>
<description>ICCID is incorrect</description><responseCode>3</responseCode>
11 Fail <error>0</error> <responseCode>1</responseCode>
<description>Charge unsuccessful Can not find target ISDN: 62227460</description>
12 Fail <error>0</error> <responseCode>3</responseCode>
<description>Unsuccessful! You have not had anypay account</description>
13 Fail <error>0</error> <responseCode>13</responseCode>
<description>Unsuccessful! You do not have enough money in anypay account</description>
14 Fail Reason: amount is not correct format
- It is integer number, example: 100 or 200, not 200.5, 200.0
- Amount is between 1 and 1000000
Response:
<error>0</error> <responseCode>3</responseCode>
<description>Amount must be equal or larger than 1 BIF and less than or equal 1 000 000
BIF</description>
1111 Fail Reason: System is overload
<error>0</error> <responseCode>1111</responseCode>
<description>Unsucessful</description>
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package qrcode;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.openide.util.Exceptions;
/**
*
* @author Administrator
*/
public class AnypayPubClient {
//Create socket
String hostname = "10.225.6.73";
int port = 8128;
InetAddress addr = InetAddress.getByName(hostname);
Socket sock = new Socket(addr, port);
sock.setSoTimeout(5 * 60 * 1000);
//Send header
String path = "/BCCSGateway?wsdl";
BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream(), "UTF-8"));
// You can use "UTF8" for compatibility with the Microsoft virtual machine.
wr.write("POST " + path + " HTTP/1.0\r\n");
wr.write("Host: " + hostname + "\r\n");
wr.write("Content-Length: " + req.length() + "\r\n");
wr.write("Content-Type: text/xml; charset=\"utf-8\"\r\n");
wr.write("\r\n");
//Send data
wr.write(req);
wr.flush();
// Response
BufferedReader rd = new BufferedReader(new InputStreamReader(sock.getInputStream()));
String strtemp = "";
while ((strtemp = rd.readLine()) != null) {
line.append(strtemp);
}
} catch (Exception e) {
e.printStackTrace();
}
String rs = line.toString();
rs = htmlspecialcharsDecode(rs);
logger.info(rs);
return rs;
}
}
static Map<String, String> html_specialchars_table = new Hashtable<String, String>();
static {
html_specialchars_table.put("<", "<");
html_specialchars_table.put(">", ">");
html_specialchars_table.put("&", "&");
html_specialchars_table.put(""", "\"");
html_specialchars_table.put("'", "'");
}