MYPAY LINK In-App Payment Design Outline
Security Design
In order to integrate the payment process more closely within the website or in-app transaction process, we designed In-App Payment (IAP mode), and still maintain that all payment requests can only be initiated from the web server of the designated store through HTTPS Encrypted transmission. The transaction information is not sent by the consumer, which can ensure that the information is not tampered with by the consumer. All payment information is forwarded and processed through the MYPAY LINK payment gateway, and the special store does not need to deal with the consumer's payment process and security control.
Data Verification
There is a set of verification codes calculated by the hash function in the transaction parameters, which are used for data verification to ensure the correctness of the data. In most transaction modes, the authorized store handles the payment process on the original page. The authorized store only needs to ensure that the connection with MYPAY LINK is normal to ensure transaction security and ensure data security.
System Infrastructure
All requests and quiries can only be initiated through the web server, and the store uses the server-side service to initiate transactions to prevent the transaction data from being tampered with or intercepted by consumers. To ensure transaction security, MYPAY LINK only accept HTTPS connection, and only accepts TLS1.2 or above protocols.
Supported request methods of MYPAY LINK
MYPAY LINK offer 6 request methods for application scenarios of transmission & query, as follows:
(1)Payment Request: When user purchases one ore more products in store, the store initiates the payment request to the system.
(2)Query Transaction: When user was concerned about the status of the transaction, use this method to checkout the latest status of transaction.
(3)Refund Request: After consumers apply for a refund request due to transaction disputes and other circumstances, can execute this method for refund transaction. You can also apply the refund from the MyPAY payment dashboard.
(4)Cancel the Refund Request: when a refund request is still in process queue, use this API to cancel the refund request.
(5)Query Electronic Invoice Status: This method can be used to query about the real-time issuance status of electronic invoices.
(6)Transaction Callback Notification: When the status of transaction be changed, the system will automatically send a callback notification to your webhook entry point.
※In order to fit different business models, we provide two request mode for STORE or AGENT: Store: use special store online transaction request parameters Agent / Dealer (such as online store service providers): use agent mode initial the transaction request for a special store.
Our API use HTTPS connection, and only accept POST method for any transaction requests.
- Service URI and other information::
(Store Mode) API entry point |
sandbox |
https://pay.usecase.cc/api/init |
---|---|---|
live |
https://ka.mypay.tw/api/init |
|
(Agnet Mode) API entry point |
sandbox |
https://pay.usecase.cc/api/agent |
live |
https://ka.mypay.tw/api/agent |
|
MYPAY library URL |
sandbox |
https://iap.usecase.cc/plugins/jQuery/jquery-3.3.1.min.js |
https://iap.usecase.cc/InAppPayment.js |
||
live |
https://iap.mypay.tw/plugins/jQuery/jquery-3.3.1.min.js |
|
https://iap.mypay.tw/InAppPayment.js |
||
Data encryption method |
AES 256 encrypt + base64 encode (Appendix IV Data encryption method) |
|
Encryption key |
The key will be sent via mail or obtained from the MyPay payment dashboard |
|
InAppPaymentToken |
obtained from the MyPay payment dashboard |
|
Text encoding |
Always use UTF-8 compatible encoding |
Payment Request
For transaction security, the payment request is divided two steps:
The first step: the store website initiates a request, and mypay returns the payment tool options. The second step: When the payment is confirmed, the server of the special store initiates the payment request.
- Overall flow:
First step, and display the payment plugin in client side.
sandbox:
<script src="https://iap.usecase.cc/plugins/jQuery/jquery-3.3.1.min.js"></script>
<script src="https://iap.usecase.cc/InAppPayment.js"></script>
live:
<script src="https://iap.mypay.tw/plugins/jQuery/jquery-3.3.1.min.js"></script>
<script src="https://iap.mypay.tw/InAppPayment.js"></script>
On the right side is the MYPAY LINK javascript library to be loaded by the special store/agent
Need to load reference library in the html HEAD for display the payment plugin .
InAppPayment
var InAppPaymentObject = InAppPayment( Config, PaymentToolCss , PaymentToolEvent );
First step, initial the payment plugin and display.
Config
var Config = {
"IAPToken" : "$2y$10$zzhK/pSgmiD2k8wzvaQnwe4//w8.c1g.nAuVLlUtxIyxe",
"EncryptedData": "+5Xk/vfrDhHCH8g38oPMNB5mFZaEXf8pbAHORETKEAAbZGj/cVrScDufUjDtKZkGoTRPixUtYH6yQVw==",
"IAPPaymentPage" : "all" ,
"StoreType" : "store",
"Checkout" : "checkout",
"IsShowInPaymentPage" : "true",
"IsUseStorePage" : "false",
"TotalPrice" : "99"
};
Parameter | Type | Description | Require |
---|---|---|---|
IAPToken | string | InAppPaymentToken of Store or Agnet | Require |
EncryptedData | string | The encrypted string of pfn & store_id with AES-256 encryption method | Require |
IAPPaymentPage | string | The tag ID of HTML element witch need to display the payment plugin | Require |
StoreType | string | special store use "store", Agent / Dealer use "agent" | Require |
Checkout | string | The consumer presses a button that will take the purchase process to the next step. MUST be the ID of the html tag | Require |
Parameter | Type | Description | Require |
---|---|---|---|
IsShowInPaymentPage | string | The process of determining the outcome of the transaction. "true" means that the transaction result webpage is displayed in the IAPPaymentPage, and "false" means that the page leads to the transaction result webpage. | Require |
IsUseStorePage | string | Decide whether the transaction result page is customized. "true" means to use the transaction result webpage designed by the special store/dealer, and "false" means to use the transaction result webpage preset by MyPay. | Require |
TotalPrice | string | The total amount of the order, the same as the cost of the transaction information return parameter | If apple pay or google pay is used, it is a necessary field |
EncryptedData
<?php
// store or agent's AES-256 key
$key = "IQBMd2z1iu6TkMaWrUSHOu";
$size = 16;
// encrypt process
function encrypt($fields, $key)
{
$data = json_encode($fields);
$size = openssl_cipher_iv_length('AES-256-CBC');
$iv = openssl_random_pseudo_bytes($size);
$data = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
$data = base64_encode($iv . $data);
return $data;
}
// return encrypted string
echo encrypt( array(
'store_uid' => 'L1230411247895',
'pfn' => '3'
) , $key)
?>
Parameter | Type | Description | Require |
---|---|---|---|
store_uid | string | Special store's Business UID | Require |
pfn | string | Payment methods | Require |
PaymentToolCss
var PaymentToolCss = {
"language" : "zh-TW" ,
"currency" : "TWD"
};
Parameter | Type | Description | Require |
---|---|---|---|
language | string | Language displayed on the payment tool screen, the default is traditional Chinese | Require |
currency | string | Currency as the payment tool, the default is New Taiwan Dollar | Require |
PaymentToolEvent
let PaymentToolEvent = {
"errorHandler" : show_error,
"finishTransaction" : endT
};
function show_error(code,msg){
console.log(code);
console.log(msg);
}
function endT(){
let trade_token = {
tradeToken : paytool.getTradeToken()
};
$.get("./store_iap_transaction.php" , trade_token , function(result){
});
}
Parameter | Type | Description | Require |
---|---|---|---|
errorHandler | javascript function | when the library throw error will call this function | Require |
finishTransaction | javascript function | whe user complected the google pay or apple pay process, will call this function. no input parameter. |
errorHandler input parameters
Parameter | Type | Description |
---|---|---|
code | int | Error Code |
msg | string | Error Message |
InAppPaymentObject
InAppPaymentObject.getTradeToken
var TradeToken = InAppPaymentObject.getTradeToken();
Obtain TradeToken. Call this method before the request initiated on the special store/agent server side. Get the HASH value, and the Store/Agent's server side use it to launch the payment process.
TradeToken
Parameter | Type | Description |
---|---|---|
TradeToken | string | The parameters required by the Store/Agent's server to initiate a payment request. |
InAppPaymentObject.setPaymentToolCss
var Css = {
"language" : "zh-TW" ,
"currency" : "TWD"
};
InAppPaymentObject.setPaymentToolCss(Css);
Modify the PaymentToolCss setting on the payment plugin screen. When consumers switch the text language or payment currency on the checkout page, Use this function to change the language displayed on the payment tool screen or the currency of payment.
Css
Parameter | Type | Description | Require |
---|---|---|---|
language | string | Language displayed on the payment plugin screen (see Appendix 5: Switching Supported Languages) | Require |
currency | string | The currency used by the payment plugin, the default is New Taiwan Dollar (Appendix 7: Support transaction currency parameters) | Require |
InAppPaymentObject.showButton
var button = "Checkout";
InAppPaymentObject.showButton(button);
Switch between Google pay, Apple pay or the original button of the website. It only needs to be used when the pfn parameter only passes Google pay or Apple pay. Consumers switch between different payment tools, and the buttons can be changed accordingly.
button
Parameter | Type | Description | Require |
---|---|---|---|
button | string | Only accept "Checkout"、"GooglePay" and "ApplePay"。 | Require |
When the payment is confirmed in the second step, the special store server initiates the payment request
<?php
// AGNET UID
$storeUid = "2891518800047";
// AGNET's key
$key = "AYTid9ACcjGaTK6V3zWmMkyrQS08Ndcx";
// info of products
$payment = array();
$payment['store_uid'] = "2891518800047";
$payment['user_data']['user_id'] = "phper";
$payment['user_data']['user_name'] = "user_name";
$payment['user_data']["user_real_name"] = "user_real_name";
$payment['user_data']["ip"] = "127.0.0.1";
$payment['order_id'] = "2020020210001";
$payment['cost'] = 55;
$payment['currency'] = 'TWD';
$payment['items'] = [['id' => '1',
'name' => 'product_name',
'cost' => '55',
'amount' => '1',
'total' => '55']];
$payment['trade_token'] = '$2y$10$07c0Ia3T.EEz4/7y8FHmj.YTL5bx27Dbw98YifVqgckcn.o44Iy6y';
// encrypt method
function encrypt($fields, $key)
{
$data = json_encode($fields);
$size = openssl_cipher_iv_length('AES-256-CBC');
$iv = openssl_random_pseudo_bytes($size);
$data = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
$data = base64_encode($iv . $data);
return $data;
}
// payload of request
$postData = array();
$postData['agent_uid'] = $storeUid;
$postData['service'] = encrypt(array(
'service_name' => 'api',
'cmd' => 'api/iaptransaction'
), $key);
$postData['encry_data'] = encrypt($payment, $key);
// send the request
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($ch, CURLOPT_URL, "https://pay.usecase.cc/api/agent");
curl_setopt($ch, CURLOPT_URL, "http://pay.mypay.com.tw/api/agent");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
print_r($result);
?>
<?php
// STORE UID
$storeUid = "289151880005";
// STORE's KEY
$key = "AYTid9ACcjGaTK6V3zWmMkyrQS08N";
// info of products
$payment = array();
$payment['store_uid'] = "289151880005";
$payment['user_data']['user_id'] = "phper";
$payment['user_data']['user_name'] = "金城武";
$payment['user_data']["user_real_name"] = "金城武";
$payment['user_data']["ip"] = "127.0.0.1";
$payment['order_id'] = "2020020210001";
$payment['cost'] = 55;
$payment['currency'] = 'TWD';
$payment['items'] = [['id' => '1',
'name' => '冰拿鐵',
'cost' => '55',
'amount' => '1',
'total' => '55']];
$payment['trade_token'] = '$2y$10$07c0Ia3T.EEz4/7y8FHmj.YTL5bx27Dbw98YifVqgckcn.o44Iy6y';
// encrypt method
function encrypt($fields, $key)
{
$data = json_encode($fields);
$size = openssl_cipher_iv_length('AES-256-CBC');
$iv = openssl_random_pseudo_bytes($size);
$data = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
$data = base64_encode($iv . $data);
return $data;
}
// payload of request
$postData = array();
$postData['store_uid'] = $storeUid;
$postData['service'] = encrypt(array(
'service_name' => 'api',
'cmd' => 'api/iaptransaction'
), $key);
$postData['encry_data'] = encrypt($payment, $key);
// send the request
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($ch, CURLOPT_URL, "https://pay.usecase.cc/api/init");
curl_setopt($ch, CURLOPT_URL, "http://pay.mypay.com.tw/api/init");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
print_r($result);
?>
/*
The case of java payment request, there are four files in total, if you want to use it, please put it in the same directory
*/
import java.net.URLEncoder;
import java.util.*;
import static java.nio.charset.StandardCharsets.UTF_8;
public class Main {
public static void main(String[] args) {
String store_uid = "A1234567890001";
String aes_key = "lRT6U5K3NKHqIjQeGB7zz6SsdqQvkKzF";
try {
Order order = new Order();
// 訂單 json 然後加密
String data_json = order.InitOrderParameters(store_uid);
byte[] data_encode = EncryUtil.encrypt(data_json.getBytes(UTF_8), aes_key.getBytes(UTF_8));
// 組成服務 json
String svr_json = order.InitServiceParameters("api", "api/iaptransaction");
byte[] svr_encode = EncryUtil.encrypt(svr_json.getBytes(UTF_8), aes_key.getBytes(UTF_8));
// 將加密資料轉成Base64
Base64.Encoder encoder = Base64.getEncoder();
String data_toBase64 = encoder.encodeToString(data_encode);
String svr_toBase64 = encoder.encodeToString(svr_encode);
// Base64需要使用UrlEncode做傳輸
String data_toUrlEncode = URLEncoder.encode(data_toBase64, "UTF-8");
String svr_toUrlEncode = URLEncoder.encode(svr_toBase64, "UTF-8");
// 組成 query 字串
String qstr = "store_uid=" + store_uid + "&service=" + svr_toUrlEncode + "&encry_data=" + data_toUrlEncode;
// qstr = "store_uid=A1234567890001&service=r370iplmiXcvgA4hzbjdO54OarHiZEvvlaVynjStPHT9q4%2bs6fxqBNQPuqQdkh9U8ugWwQzSo8PFoOgJ1%2fnq%2fw%3d%3d&encry_data=r370iplmiXcvgA4hzbjdOyymf2umsEtNEhCrRsFLnxUzeeuggk46yiXCl1OHp7vFaDXvxyWEu3m4UPXtGa%2bImAyOvaHb%2f1bP0FDiijVozHh2I6jrLIdSsivK7Pon1a1PDI%2bA4HrXSeZJAkkyivEDWFD1bk6hJHe2EWJ6%2biXjsaUKsVIwzrLwmgnsC5nI51VnwlbrM25R1cmEwiuE7TVg0qtMjs7pHKM25ouVIl3Ep%2bzearS7okQK%2fMeM0%2bo6%2fbKRMNy51iXwcPEnNAyjvd2K5Y5iIAzHxx8VqO9Y47Ih6Cnt6eo%2fGUAyWMP5TZe93fTv";
System.out.println(qstr);
order.HttpPost(qstr);
}
catch(Exception ex)
{
System.out.println(ex.getMessage());
}
}
}
public interface IOrder {
String InitOrderParameters(String order_uid);
String InitServiceParameters(String service_name, String cmd);
String HttpPost(String qstr);
}
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
public class Order implements IOrder {
@Override
public String InitOrderParameters(String store_uid) {
// 訂單
LinkedHashMap<String, String> dto = new LinkedHashMap<String, String>();
dto.put("store_uid", store_uid);
dto.put("item", "1");
dto.put("cost", "10");
dto.put("user_id", "phper");
dto.put("order_id", "1234567890");
dto.put("ip", "192.168.0.10");
dto.put("pfn", "ALL");
// 產品清單列表
dto.put("i_0_id", "0886449");
dto.put("i_0_name", "商品名稱");
dto.put("i_0_cost", "10");
dto.put("i_0_amount", "10");
dto.put("i_0_total", "10");
/*
int start_id = 886449;
for(int i = 0; i < 5; i++)
{
dto.put("i_" + String.valueOf(i) + "_id", String.valueOf(start_id + i));
dto.put("i_" + String.valueOf(i) + "_name", "商品名稱" + String.valueOf(i));
dto.put("i_" + String.valueOf(i) + "_cost", "10");
dto.put("i_" + String.valueOf(i) + "_amount", "10");
dto.put("i_" + String.valueOf(i) + "_total", "100");
}
*/
// 序列化
ObjectMapper om = new ObjectMapper();
String data_parameters_str = "";
try {
data_parameters_str = om.writeValueAsString(dto);
return data_parameters_str;
// System.out.print(data_parameters_str);
}
catch (Exception ex)
{
System.out.print(ex.getMessage());
}
return "";
}
@Override
public String InitServiceParameters(String service_name, String cmd) {
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
map.put("service_name", service_name);
map.put("cmd", cmd);
// 序列化
ObjectMapper om = new ObjectMapper();
String service_parameters_str = "";
try {
service_parameters_str = om.writeValueAsString(map);
return service_parameters_str;
// System.out.print(service_parameters_str);
}
catch (Exception ex)
{
System.out.print(ex.getMessage());
}
return "";
}
@Override
public String HttpPost(String qstr) {
try {
// 資料
byte[] qstr_bytes = qstr.getBytes(StandardCharsets.UTF_8);
String url_str = "https://pay.usecase.cc/api/init";
URL iurl = new URL(url_str);
SSLContext sc = SSLContext.getInstance("TLSv1.2"); // $NON-NLS-1$
sc.init(null, null, new java.security.SecureRandom());
HttpsURLConnection con = (HttpsURLConnection) iurl.openConnection();
con.setSSLSocketFactory(sc.getSocketFactory());
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("Content-Length", String.valueOf(qstr_bytes.length));
con.setRequestProperty("Accept-Charset", "UTF-8");
con.setDoOutput(true);
con.setDoInput(true);
con.getOutputStream().write(qstr.getBytes(Charset.forName("UTF-8")));
con.getOutputStream().flush();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
try {
String res = response.toString();
System.out.println(res);
} finally {
in.close();
}
System.out.println("Resp Code:" + con.getResponseCode());
System.out.println("Resp Message:"+ con.getResponseMessage());
}
catch (Exception ex)
{
System.out.println(ex.getMessage());
}
return "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
}
}
import org.spongycastle.crypto.engines.AESFastEngine;
import org.spongycastle.crypto.modes.CBCBlockCipher;
import org.spongycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.spongycastle.crypto.params.KeyParameter;
import org.spongycastle.crypto.params.ParametersWithIV;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.security.Security;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class EncryUtil {
public static byte[] encrypt(byte[] data, byte[] key)
{
// 16 bytes is the IV size for AES256
try
{
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESFastEngine()));
// Random iv
SecureRandom rng = new SecureRandom();
byte[] ivBytes = new byte[16];
rng.nextBytes(ivBytes);
cipher.init(true, new ParametersWithIV(new KeyParameter(key), ivBytes));
byte[] outBuf = new byte[cipher.getOutputSize(data.length)];
int processed = cipher.processBytes(data, 0, data.length, outBuf, 0);
processed += cipher.doFinal(outBuf, processed);
byte[] outBuf2 = new byte[processed + 16]; // Make room for iv
System.arraycopy(ivBytes, 0, outBuf2, 0, 16); // Add iv
System.arraycopy(outBuf, 0, outBuf2, 16, processed); // Then the encrypted data
return outBuf2;
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
}
/*
Complete example
https://drive.google.com/file/d/10W8uOXfDzOg4oj_iWPwgC0JicRw3cjRm/view?usp=sharing
*/
/*
There are five files in total
Except Order.cs
Others are placed in the same directory
*/
Order.cs
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
namespace PaymentOrder
{
//0.建議使用.net framework4.5以上版本
//1.請透過NuGet安裝Newtonsoft.Json,若.net framework小於4.5請安裝Newtonsoft.Json 7.0以下版本
//2.若貴司.net framework小於4 可能無法使用dynamic,若是自行組陣列
//3.若貴司.net framework小於3.5 可能無法使用AES類別,若是參閱微軟網站使用較舊方式進行加密
//4.若貴司.net framework小於3.5 可能沒有Linq可使用,故data只能組字串,Newtonsoft.Json也可能無法使用
public class Order
{
public string SendOrder(PaymentOrder.DTO.OrderDataDTO dto)
{
//建立傳輸格式
string data_json = CreateDataParameter(dto);//這裡dto內僅示意基本參數,請依規格表及需求進行調整
string svr_json = CreateServiceParameter("api", "api/iaptransaction");//依API種類調整
//取得加密用的Key 請依貴司現況調整取得方式
string EnKey = "kLJOYpT3GMBPMoWn7bup2Cm8oG9hwQW4";
//產生AES向量
var IV = GetBytesIV();
//進行加密
var data_encode = Encrypting(data_json, EnKey, IV);
var svr_encode = Encrypting(svr_json, EnKey, IV);
//將加密資料轉成Base64
string data_toBase64 = Convert.ToBase64String(data_encode);
string svr_toBase64 = Convert.ToBase64String(svr_encode);
//Base64需要使用UrlEncode做傳輸
string data_toUrlEncode = HttpUtility.UrlEncode(data_toBase64);
string svr_toUrlEncode = HttpUtility.UrlEncode(svr_toBase64);
//組成待送資料
string apiPath = "https://pay.usecase.cc/api/init";
NameValueCollection pars = new NameValueCollection();
pars["store_uid"] = dto.StoreId;
pars["service"] = svr_toUrlEncode;
pars["encry_data"] = data_toUrlEncode;
//僅限走https的Tls 1.1以上版本
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
//發送至遠端
var result = HttpPost(apiPath, pars);
//請依規格表解析結果
return result;
}
private string CreateDataParameter(DTO.OrderDataDTO dto)
{
//透過Json將OrderDataRequest轉換成ExpandoObject,
//使用dynamic目的是訂單的格式是i_[]_xxx這樣可以直接由物件產生成json,而不用組字串
var _toExternalData = new PaymentOrder.DTO.OrderDataRequest
{
cost = dto.Cost,
store_uid = dto.StoreId,
pfn = dto.PFN,
user_id = dto.UserId,
ip = string.Empty,
item = dto.Item,
order_id = dto.OrderId
};
if (HttpContext.Current != null)
{
_toExternalData.ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"].ToString();
//REMOTE_ADDR可能會因客戶或貴司網路不同而無法取得IP,請依貴司環境下作調整
//參閱
//https://msdn.microsoft.com/en-us/library/ms524602(v=vs.90).aspx
//https://social.msdn.microsoft.com/Forums/zh-TW/5638f510-ba03-4dac-a6fb-98b4e202ecc6/httpclientip-remoteaddr-?forum=236
//http://devco.re/blog/2014/06/19/client-ip-detection/
}
var initJson = JsonConvert.SerializeObject(_toExternalData, Formatting.None);
dynamic toExternalData = JsonConvert.DeserializeObject<System.Dynamic.ExpandoObject>(initJson);
var p = toExternalData as IDictionary<String, object>;
int cnt = 0;
if (dto.ProductData != null)
{
dto.ProductData.ForEach(item =>
{
p["i_" + cnt.ToString() + "_id"] = item.ID;
p["i_" + cnt.ToString() + "_name"] = item.Name;
p["i_" + cnt.ToString() + "_cost"] = item.Cost;
p["i_" + cnt.ToString() + "_amount"] = item.Amount;
p["i_" + cnt.ToString() + "_total"] = item.Total;
cnt++;
});
}
var json = JsonConvert.SerializeObject(toExternalData, Formatting.None);
return json;
}
private string CreateServiceParameter(string service_name, string cmd)
{
PaymentOrder.DTO.OrderServiceRequest serviceDTO = new DTO.OrderServiceRequest()
{
service_name = service_name,
cmd = cmd
};
var json = JsonConvert.SerializeObject(serviceDTO, Formatting.None);
return json;
}
private byte[] Encrypting(string data, string key, byte[] byteIV)
{
var byteKey = System.Text.Encoding.UTF8.GetBytes(key);
var enBytes = AES_Encrypt(data, byteKey, byteIV);
return BytesAdd(byteIV, enBytes);
}
private byte[] AES_Encrypt(string original, byte[] key, byte[] iv)
{
try
{
var data = Encoding.UTF8.GetBytes(original);
var cipher = Aes.Create().CreateEncryptor(key, iv);
var de = cipher.TransformFinalBlock(data, 0, data.Length);
return de;
}
catch
{
return null;
}
}
private byte[] BytesAdd(byte[] a, params byte[][] arryB)
{
List<byte> c = new List<byte>();
c.AddRange(a);
arryB.ToList().ForEach(b =>
{
c.AddRange(b);
});
return c.ToArray();
}
private string HttpPost(string url, NameValueCollection pars)
{
if (string.IsNullOrWhiteSpace(url))
throw new NullReferenceException("Post傳送的網址不可為空");
string result = string.Empty;
string param = string.Empty;
if (pars.Count > 0)
{
pars.AllKeys.ToList().ForEach(key =>
{
param += key + "=" + pars[key] + "&";
});
if (param[param.Length - 1] == '&')
{
param = param.Remove(param.Length - 1);
}
}
byte[] bs = Encoding.UTF8.GetBytes(param);
try
{
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = bs.Length;
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(bs, 0, bs.Length);
}
using (WebResponse wr = req.GetResponse())
{
Encoding myEncoding = Encoding.GetEncoding("UTF-8");
using (StreamReader myStreamReader = new StreamReader(wr.GetResponseStream(), myEncoding))
{
result = myStreamReader.ReadToEnd();
}
}
req = null;
}
catch (WebException ex)
{
throw new WebException(ex.Message + "params : " + param, ex, ex.Status, ex.Response);
}
return result;
}
/// <summary>
/// 產生AES的IV
/// </summary>
/// <returns></returns>
private static byte[] GetBytesIV()
{
var aes = System.Security.Cryptography.AesCryptoServiceProvider.Create();
aes.KeySize = 256;
aes.GenerateIV();
return aes.IV;
}
}
}
ProductDataDTO.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace PaymentOrder.DTO
{
public class ProductDataDTO
{
public string ID { get; set; }
public string Name { get; set; }
public string Cost { get; set; }
public string Amount { get; set; }
public string Total { get; set; }
}
}
OrderServiceRequest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace PaymentOrder.DTO
{
public class OrderServiceRequest
{
public string service_name { get; set; }
public string cmd { get; set; }
}
}
OrderDataRequest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace PaymentOrder.DTO
{
public class OrderDataRequest
{
public string store_uid { get; set; }
public string item { get; set; }
public string cost { get; set; }
public string user_id { get; set; }
public string order_id { get; set; }
public string ip { get; set; }
public string pfn { get; set; }
}
}
OrderDataDTO.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace PaymentOrder.DTO
{
public class OrderDataDTO
{
public string StoreId { get; set; }
public string Item { get; set; }
public string Cost { get; set; }
public string UserId { get; set; }
public string OrderId { get; set; }
public string PFN { get; set; }
public List<ProductDataDTO> ProductData { get; set; }
}
}
/*
Complete example
https://drive.google.com/file/d/1qMRgQ9wHEuTRGBNa4GULKzzLOK3R3RQG/view?usp=sharing
*/
This transaction request parameter contains the transaction order number, the key used for the query, and the payment URL. Your company can also bind this transaction order number to your company’s consumer order, and we will report the real-time transaction information by POST through the active report mechanism. The Callback URL can be in the management system After the service is activated, the system will actively return the order status. (On the right is an example of the interface between dealers and special stores)
Dealer/Agent transaction request parameters
<?php
service :
{
"service_name": "api",
"cmd": "api/iaptransaction"
}
?>
Parameter | Type | Description |
---|---|---|
agent_uid | string(16) | Dealer/Agent's Business UID |
service | JSON | service name |
encry_data | text | Encrypted data in the transaction information field (JSON format). For the description of the transaction information field, please refer to the following table-Transaction information report parameters |
Special store transaction request parameters
<?php
service :
{
"service_name": "api",
"cmd": "api/iaptransaction"
}
?>
Parameter | Type | Description |
---|---|---|
store_uid | string(16) | Special store's Business UID |
service | JSON | service name |
encry_data | text | Encrypted data in the transaction information field (JSON format). For the description of the transaction information field, please refer to the following table-Transaction information report parameters |
Transaction request parameters
Parameter | Type | Description | Require |
---|---|---|---|
store_uid | string(16) | Special store's Business UID | Require |
items | array | Product information (please refer to the product information field below) | Require |
cost | int(7) | The total amount of the order = the total price of the items + the discount + shipping (if it is a regular fixed-amount transaction, this is the deductible amount for each period) | Require |
currency | string(3) | Default transaction currency (if not filled in, the default is TWD, please refer to Appendix 7 for available currency parameters) | |
order_id | string(50) | Order number (the longest order number is 50bytes, it is recommended not to reuse the same number) | Require |
discount | int(7) | Discount (how much has a negative number) | |
shipping_fee | int(7) | shipping costs | |
user_data | json object | Consumer information (please refer to the consumer information column below) | Require |
success_returl | string(200) | The URL of the successful transaction redirect page, without parameters, payment system will redirect to the page with URL setting in the MyPay payment dashboard | |
failure_returl | string(200) | The URL of the redirect page for transaction failure. There is no parameter, payment system will redirect to the page with the URL setting in the MyPay payment dashboard | |
trade_token | string | The string obtained by calling getTradeToken on the consumer's browser | Require |
echo_0 | string(100) | Custom return parameters 1 | |
echo_1 | string(100) | Custom return parameters 2 | |
echo_2 | string(100) | Custom return parameters 3 | |
echo_3 | string(100) | Custom return parameters 4 | |
echo_4 | string(100) | Custom return parameters 5 | |
creditcard_is_automatic_payment | string(1) | 0: Self-Ask for payment, 1: Auto-Ask for payment (default) | |
creditcard_invoice | string(1) | 1: Issue invoice in creditcard Ask for payment (default), 2: Issue invoice in creditcard authorize |
Consumer Information
Parameter | Type | Description | Require |
---|---|---|---|
user_id | string(200) | The consumer registered the account name in the store | Require |
ip | string(15) | Consumer Internet Sources IP | Require |
user_name | string(100) | Consumer name | Require |
user_real_name | string(100) | Consumer's real name | Require |
user_address | string(100) | Consumer address | Require |
user_sn_type | int(1) | 1: Identity card, 2: Unified ID number, 3: Passport number (1 for consumers who are nationals, 2 or 3 for foreigners) | |
user_sn | string(16) | Consumer ID Number/Unified ID Number/Passport Number | |
user_phone | int(16) | Consumer home phone (daytime phone) | |
user_cellphone_code | string(3) | Consumer mobile phone country code (default 886) | |
user_cellphone | int(16) | Consumer mobile phone | Require |
user_email | string(100) | Consumer E-Mail | Require |
user_birthday | string(8) | Consumer's birthday (format is YYYYMMDD, such as 20090916) |
Product Information
Parameter | Type | Description | Require |
---|---|---|---|
id | string(20) | Product Number / ID | Require |
name | string(20) | Product Name | Require |
cost | string(10) | Product Price, Cost | Require |
amount | string(10) | Amount of Product | Require |
total | string(20) | Sub-total | Require |
Return data (JSON format)
Parameter | Description |
---|---|
key | Transaction verification key Query Transaction need this info. |
uid | Payment Hub Transaction serial number Query Transaction need this info. |
code | Transaction return code |
cardno | Bank port return code |
acode | Bank transaction authorization code |
order_id | Order number of your store |
user_id | Consumer account ID |
cost | Total transaction amount |
currency | Original transaction currency |
actual_cost | Actual transaction amount |
actual_currency | Actual transaction currency |
pfn | Payment method |
finishtime | Transaction completion time (YYYYMMDDHHmmss) |
msg | Return message |
echo_0 | Custom return parameter 1 |
echo_1 | Custom return parameter 2 |
echo_2 | Custom return parameter 3 |
echo_3 | Custom return parameter 4 |
echo_4 | Custom return parameter 5 |
result_type | The payment method CSTORECODE (super business code) and E_COLLECTION (virtual account number) are valid result_content format: 1 Url 2 Html 3 Xml 4 Json 5 Csv 6 Stream |
result_content | The payment methods CSTORECODE (super business code) and E_COLLECTION (virtual account number) are valid, please refer to the description of result_content below for the description of the fields |
result_content Description
E_COLLECTION(Bank Virtual account)
Parameter | Description |
---|---|
LimitExpiredDate | Payment deadline |
BankCode | Bank Code |
SourceCode | Payment code |
BusinessName | account title |
Cost | Payment amount |
CSTORECODE(Convenience store payment code)
Parameter | Description |
---|---|
StoreCode | Convenience store code; currently FAMIPORT, IBON, LIFEET |
ImageCode | Barcode type: BARCODE-C39 or QRCODE |
ResultCode | JSON format; PinCode: Payment code (this code can be entered in the supermarket equipment and printed out for payment) BarCode1: Barcode code in the first column BarCode2: Barcode code in the second column BarCode3: Third Barcode code Barcode type: BARCODE-C39 (applicable to FAMIPORT, LIFEET) Three bar code images must be displayed for supermarkets to scan: BarCode1, BarCode2, BarCode3 Barcode type: QRCODE (for IBON) The QRCODE needs to be displayed, and the content is PinCode. |
BusinessName | Business Name |
Cost | Cost |
LimitExpiredDate | Payment deadline |
Query Transaction
<?php
// 特約商店商務代號
$agentUid = "A1111111111001";
// 特約商店金鑰
$key = "hSVkUjvkcKqzn4FF9BFHLarhV9puQmAV";
// 商品資料
$order = array();
$order['uid'] = "25160";
$order['key'] = "4d706668d98c26e11bae827be7e7efcd";
// 加密方法
function encrypt($fields, $key)
{
$data = json_encode($fields);
$size = openssl_cipher_iv_length('AES-256-CBC');
$iv = openssl_random_pseudo_bytes($size);
$data = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
$data = base64_encode($iv . $data);
return $data;
}
// 送出欄位
$postData = array();
$postData['agent_uid'] = $agentUid;
$postData['service'] = encrypt(array(
'service_name' => 'api',
'cmd' => 'api/queryorder'
), $key);
$postData['encry_data'] = encrypt($order, $key);
// 資料送出
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, "https://pay.usecase.cc/api/agent");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
// 回傳 JSON 內容
print_R($result);
?>
<?php
// 特約商店商務代號
$storeUid = "398800730001";
// 特約商店金鑰
$key = "hSVkUjvkcKqzn4FF9BFHLarhV9puQmAV";
// 商品資料
$order = array();
$order['uid'] = "25160";
$order['key'] = "4d706668d98c26e11bae827be7e7efcd";
// 加密方法
function encrypt($fields, $key)
{
$data = json_encode($fields);
$size = openssl_cipher_iv_length('AES-256-CBC');
$iv = openssl_random_pseudo_bytes($size);
$data = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
$data = base64_encode($iv . $data);
return $data;
}
// 送出欄位
$postData = array();
$postData['store_uid'] = $storeUid;
$postData['service'] = encrypt(array(
'service_name' => 'api',
'cmd' => 'api/queryorder'
), $key);
$postData['encry_data'] = encrypt($order, $key);
// 資料送出
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, "https://pay.usecase.cc/api/init");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
// 回傳 JSON 內容
print_R($result);
?>
When the system informs you that the transaction result is abnormal and your company cannot receive the order information normally, you can update the order status through the transaction result query service, ensure the correct transaction result.
When the query rules are met, the transaction fields will be returned, and the original query fields will be returned if the query conditions are not met. The correct query result will be returned only if the conditions are met. In addition to single query, transaction query service can also query mulitple result at one time.
Dealer/Agent transaction query parameters
<?php
service :
{
"service_name": "api",
"cmd": "api/queryorder"
}
?>
Parameter | Type | Description |
---|---|---|
agent_uid | string(16) | Dealer/Agent's Business UID |
service | JSON | service name |
encry_data | text | Encrypted data in the transaction information field (JSON format). (Please refer to the following table-query transaction parameters), if multiple query fields are converted into arrays and substituted. |
Special store transaction query parameters
<?php
service :
{
"service_name": "api",
"cmd": "api/queryorder"
}
?>
Parameter | Description |
---|---|
store_uid | string(16) |
service | JSON |
encry_data | text |
Query transaction parameters
Parameter | Description |
---|---|
uid | Payment Hub Transaction serial number. This parameter is the return parameter from the Payment Request. refer: return parameter of the Payment Request |
key | Transaction verification key. This parameter is the return parameter from the Payment Request. refer: return parameter of the Payment Request |
Return data (JSON format)
Parameter | Description |
---|---|
key | Transaction Verification key |
uid | MYPAY LINK transaction serial number |
prc | Transaction Return Code |
cardno | card number/VA/supermarket code |
acode | Bank transaction authorization code/virtual account number/super merchant code |
order_id | The order number of the Guitedian system |
user_id | Consumer account |
cost | Total transaction amount |
currency | Original transaction currency |
actual_cost | Actual transaction amount |
actual_currency | Actual transaction currency |
love_cost | Love donation amount (currency is the same as the actual transaction currency) |
retmsg | Return message |
pfn | Payment method |
finishtime | Transaction completion time (YYYYMMDDHHmmss) |
bank_id | VA payment bank code (virtual account number) |
expired_date | Effective date (virtual account number or supermarket code) |
invoice_state | Invoice Issuing State |
invoice_date | Invoice issuance date (YYYYMMDD) |
invoice_wordtrack | Invoice wordtrack |
invoice_number | invoice number |
invoice_input_type | Consumer invoice selection type |
refund_order | The return field is optional, and the field type content is an array. When querying an order, if one or more successful refunds have been initiated, this content includes all refund orders that have been successfully refunded. |
cancel_order | The return field is optional, and the field type content is an array. When inquiring about an order, if one or more successful cancellations have been initiated, this content will include all cancellation order information for successful cancellations. |
echo_0 | Customized return parameter 1 |
echo_1 | Customized return parameter 2 |
echo_2 | Customized return parameter 3 |
echo_3 | Customized return parameter 4 |
echo_4 | Customized return parameter 5 |
result_type | Payment methods CSTORECODE (Convenience store code) and E_COLLECTION (virtual account number) are valid The format of result_content: 1 Url 2 Html 3 Xml 4 Json 5 Csv 6 Stream |
result_content | Payment methods CSTORECODE (super business code) and E_COLLECTION (virtual account number) are valid, please refer to the transaction above for the description of the fields description of result_content |
Refund Request
<?php
// 經銷商商務代號
$agentUid = "A1111111111001";
// 特約商店金鑰
$key = "Xd668CSjnXQLD26Hia8vapkOgGXAv68s";
// 商品資料
$order = array();
$order['store_uid'] = "398800730001";
$order['uid'] = "21691";
$order['key'] = "09aa8b4821b55a276d34afb81fb23191";
$order['cost'] = 10;
/*
多筆格式範例
$order = array();
$order['store_uid'] = "398800730001";
$order['rows'] = [['uid' => "21691",'key'=>’09aa8b4821b55a276d34afb81fb23191’,'cost' => 10],
['uid' => "21692",'key'=>’09aa8b4821b55a276d34afb81fb23192’,'cost' => 10]];
*/
// 加密方法
function encrypt($fields, $key)
{
$data = json_encode($fields);
$size = openssl_cipher_iv_length('AES-256-CBC');
$iv = openssl_random_pseudo_bytes($size);
$data = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
$data = base64_encode($iv . $data);
return $data;
}
// 送出欄位
$postData = array();
$postData['store_uid'] = $agentUid;
$postData['service'] = encrypt(array(
'service_name' => 'api',
'cmd' => 'api/refund'
), $key);
$postData['encry_data'] = encrypt($order, $key);
// 資料送出
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, "https://pay.usecase.cc/api/agent");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
// 回傳 JSON 內容
print_R($result);
?>
<?php
// 特約商店商務代號
$storeUid = "398800730001";
// 特約商店金鑰
$key = "Xd668CSjnXQLD26Hia8vapkOgGXAv68s";
// 商品資料
$order = array();
$order['store_uid'] = $storeUid;
$order['uid'] = "21691";
$order['key'] = "09aa8b4821b55a276d34afb81fb23191";
$order['cost'] = 10;
/*
多筆格式範例
$order = array();
$order['store_uid'] = $storeUid;
$order['rows'] = [['uid' => "21691",'key'=>’09aa8b4821b55a276d34afb81fb23191’,'cost' => 10],
['uid' => "21692",'key'=>’09aa8b4821b55a276d34afb81fb23192’,'cost' => 10]];
*/
// 加密方法
function encrypt($fields, $key)
{
$data = json_encode($fields);
$size = openssl_cipher_iv_length('AES-256-CBC');
$iv = openssl_random_pseudo_bytes($size);
$data = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
$data = base64_encode($iv . $data);
return $data;
}
// 送出欄位
$postData = array();
$postData['store_uid'] = $storeUid;
$postData['service'] = encrypt(array(
'service_name' => 'api',
'cmd' => 'api/refund'
), $key);
$postData['encry_data'] = encrypt($order, $key);
// 資料送出
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, "https://pay.usecase.cc/api/init");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
// 回傳 JSON 內容
print_R($result);
?>
If you need a refund, launch this API to make a refund request. This refund request will be temporarily held in the system refund column, and the refund will be processed in the early morning of the next day. Refundable orders are based on the transaction method of the order, please refer to Appendix 8.
Parameter Description of Refund Request of Dealer/Agent
<?php
service :
{
"service_name": "api",
"cmd": "api/refund"
}
?>
Parameter | Description |
---|---|
agent_uid | Dealer/Agent's Business UID |
service | Service name, (JSON format) encrypted data |
encry_data | Encrypted data in the refund request field (JSON format) (please refer to the refund order parameters or multiple refund order parameters in the form below). |
Parameter Description of Refund Request of Special Store
<?php
service :
{
"service_name": "api",
"cmd": "api/refund"
}
?>
Parameter | Description |
---|---|
store_uid | Special store's Business UID |
service | Service name, (JSON format) encrypted data |
encry_data | Encrypted data in the refund request field (JSON format) (please refer to the refund order parameters or multiple refund order parameters in the form below). |
Single refund request parameters
Parameter | Description |
---|---|
store_uid | Special store's Business UID |
uid | Payment Hub Transaction serial number. This parameter is the return parameter from the Payment Request. refer: return parameter of the Payment Request |
key | Transaction verification key. This parameter is the return parameter from the Payment Request. refer: return parameter of the Payment Request |
cost | The refund amount (the amount must be greater than 0 and less than or equal to the original order amount). The upper limit of the total refundable amount in the collection and payment mode is: 90% of the total grant (excluding handling fees and remittance fees) |
Multiple refund request parameters
Parameter | Description |
---|---|
store_uid | Special store's Business UID |
rows | Array data, please refer to the rows column array parameters of multiple refund orders for the content of each field |
rows field array dataset of Multiple refund request
Parameter | Description |
---|---|
uid | Payment Hub Transaction serial number. This parameter is the return parameter from the Payment Request. refer: return parameter of the Payment Request |
key | Transaction verification key. This parameter is the return parameter from the Payment Request. refer: return parameter of the Payment Request |
cost | The refund amount (the amount must be greater than 0 and less than or equal to the original order amount). The upper limit of the total refundable amount in the collection and payment mode is: 90% of the total grant (excluding handling fees and remittance fees) |
Return data (JSON format), if there are multiple entries, return format data
Parameter | Description |
---|---|
uid | Payment Hub Transaction serial number. |
key | Transaction verification key. |
code | Return Code |
msg | Return message |
Cancel Refund Request
<?php
// 經銷商商務代號
$agentUid = "A1111111111001";
// 特約商店金鑰
$key = "Xd668CSjnXQLD26Hia8vapkOgGXAv68s";
// 商品資料
$order = array();
$order['store_uid'] = "398800730001";
$order['uid'] = "21691";
$order['key'] = "09aa8b4821b55a276d34afb81fb23191";
// 加密方法
function encrypt($fields, $key)
{
$data = json_encode($fields);
$size = openssl_cipher_iv_length('AES-256-CBC');
$iv = openssl_random_pseudo_bytes($size);
$data = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
$data = base64_encode($iv . $data);
return $data;
}
// 送出欄位
$postData = array();
$postData['agent_uid'] = $agentUid;
$postData['service'] = encrypt(array(
'service_name' => 'api',
'cmd' => 'api/refundcancel'
), $key);
$postData['encry_data'] = encrypt($order, $key);
// 資料送出
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, "https://pay.usecase.cc/api/agent");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
// 回傳 JSON 內容
print_R($result);
?>
<?php
// 特約商商務代號
$storeUid = "398800730001";
// 特約商店金鑰
$key = "Xd668CSjnXQLD26Hia8vapkOgGXAv68s";
// 商品資料
$order = array();
$order['store_uid'] = "398800730001";
$order['uid'] = "21691";
$order['key'] = "09aa8b4821b55a276d34afb81fb23191";
// 加密方法
function encrypt($fields, $key)
{
$data = json_encode($fields);
$size = openssl_cipher_iv_length('AES-256-CBC');
$iv = openssl_random_pseudo_bytes($size);
$data = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
$data = base64_encode($iv . $data);
return $data;
}
// 送出欄位
$postData = array();
$postData['store_uid'] = $storeUid;
$postData['service'] = encrypt(array(
'service_name' => 'api',
'cmd' => 'api/refundcancel'
), $key);
$postData['encry_data'] = encrypt($order, $key);
// 資料送出
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, "https://pay.usecase.cc/api/init");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
// 回傳 JSON 內容
print_R($result);
?>
When a refund request is apply on the same day, it will wait for the refund in the system refund column. The system refund time is at midnight the next day to initiate a refund, so before the refund is done, you can issue this API request to cancel (5) the refund request (can also be canceled through the management interface).
Cancel refund request parameter description for Dealer/Agent
<?php
service :
{
"service_name": "api",
"cmd": "api/refundcancel"
}
?>
Parameter | Description |
---|---|
agent_uid | Dealer/Agent's Business UID |
Service | Service name, (JSON format) information material |
encry_data | Refresh the data in the cancellation refund request field (JSON format) (please check the following form for cancellation refund parameters or multiple cancellation refund parameters). |
Cancel refund request parameter description for Special Store
<?php
service :
{
"service_name": "api",
"cmd": "api/refundcancel"
}
?>
Parameter | Description |
---|---|
store_uid | Special store's Business UID |
Service | Service name, (JSON format) information material |
encry_data | Refresh the data in the cancellation refund request field (JSON format) (please check the following form for cancellation refund parameters or multiple cancellation refund parameters). |
Single cancellation refund parameters
Parameter | Description |
---|---|
store_uid | Special store's Business UID |
uid | Payment Hub Transaction serial number. This parameter is the return parameter from the Payment Request. refer: return parameter of the Payment Request |
key | Transaction verification key. This parameter is the return parameter from the Payment Request. refer: return parameter of the Payment Request |
Multiple cancellation refund parameters
Parameter | Description |
---|---|
store_uid | Special store's Business UID |
rows | Array data, please refer to the rows field array parameters of multiple cancellation refund orders for the content of each field |
rows field array dataset of Multiple cancellation refund request
Parameter | Description |
---|---|
uid | Payment Hub Transaction serial number. This parameter is the return parameter from the Payment Request. refer: return parameter of the Payment Request |
key | Transaction verification key. This parameter is the return parameter from the Payment Request. refer: return parameter of the Payment Request |
Return data (JSON format), if there are multiple entries, return data in array format
Parameter | Description |
---|---|
uid | Payment Hub Transaction serial number. |
key | Transaction verification key. |
code | Return Code |
msg | Return message |
Query Electronic invoice Status
If you have applied for the use of e-invoices through MYPAY, you can use this method to check the real-time issuance status of the current e-invoices, and the transaction inquiries include the complete information of the order. You can make individual enquiries according to your needs. When the query rules are met, the relevant transaction fields will be returned, and the original query fields will be returned if the query conditions are not met. The correct query result will be returned only if the conditions are met. In addition to single query, transaction query also provides multiple queries at a time.
Parameter Description Electronic Invoice Status Query for Dealer/Agent
<?php
service :
{
"service_name": "api",
"cmd": "api/invoice"
}
?>
Parameter | Description |
---|---|
agent_uid | Dealer/Agent's Business UID |
service | Service name, (JSON format) encrypted data |
encry_data | Encrypted data in the query transaction number field (JSON format) (please refer to the table below-query transaction number parameters). If there are multiple query fields, convert them into arrays and insert them. |
Parameter Description Electronic Invoice Status Query for Special Store
<?php
service :
{
"service_name": "api",
"cmd": "api/invoice"
}
?>
Parameter | Description |
---|---|
store_uid | Special store's Business UID |
service | Service name, (JSON format) encrypted data |
encry_data | Encrypted data in the query transaction number field (JSON format) (please refer to the table below-query transaction number parameters). If there are multiple query fields, convert them into arrays and insert them. |
Request parameters of Query Electronic Invoice Status
Parameter | Description |
---|---|
uid | Payment Hub Transaction serial number. This parameter is the return parameter from the Payment Request. refer: return parameter of the Payment Request |
key | Transaction verification key. This parameter is the return parameter from the Payment Request. refer: return parameter of the Payment Request |
Return data (JSON format)
Parameter | Description |
---|---|
uid | Payment Hub Transaction serial number.> |
key | Transaction verification key. |
prc | Final transaction status (usually: successful transaction (250,290,600, etc.), refund (230), and partial refund, please refer to Appendix 2) |
order_id | The order number of the Guitedian system |
payment_name | The name of the deduction (for regular fixed amount/for regular installment transactions) |
nois | Number of periods (regular fixed amount/special for regular installment transactions) |
group_id | Regular fixed amount/Regular installment number |
state | Invoice issuance status 0. Not processed (default) 1 Waiting for processing, 2 Invoice processing is successful 3. Invoice processing failed 4. Invoice |
date | Invoice issuance date (YYYYMMDD) |
wordtrack | Invoice word track |
number | Invoice number |
input_type | Consumer invoice selection type 1. Cloud invoice 2. Invoice donation 3. B2B |
echo_0 | Customized return parameter 1 |
echo_1 | Customized return parameter 2 |
echo_2 | Customized return parameter 3 |
echo_3 | Customized return parameter 4 |
echo_4 | Customized return parameter 5 |
Dataset of Transaction Callback
<?php
//取得回傳內容
$result = $_REQUEST;
//使用key與'uid驗證,$db[ 'key']與$db[ 'uid']為交易請求回傳欄位
//驗證資料來源
if ($result['key'] == $db[ 'key'] && $result['uid'] == $db[ 'uid']){
print("8888");
}
?>
You can set the Callback URL in the MyPay payment dashboard interface, and the system will notify you of the transaction report. The system will actively notify the Callback URL set by the system. If your company does not send back confirmation after receiving the report, MyPay system will notify once every five minutes, and will notify four times in a row. If there is still no reply, no more notification will be sent, but the E-mail notification will be sent to the technician’s mailbox or designated mailbox for your follow-up processing.
- MYPAY LINK provides three callback types: For these three types, MYPAY LINK confirms that there are these three receiving mechanisms before actively your system online.
Real-time transaction Callback: Consumers pay, don't need to leave the MYPAY LINK page to complete the transaction. Using the resend transaction in the order management will also be returned through this type.
Asynchronous transaction Callback: When consumers pay, they will leave the MYPAY LINK page to complete the transaction. MYPAY LINK will send a notification when the consumer has paid the fee or exceeded the payment time.
Order Confirmation Callback: MYPAY LINK cannot get the transaction result in a normal way. When MYPAY LINK knows the transaction result through active inquiry or reconciliation, it will actively return the transaction result in this transaction return format. When using the query function in the order function, if the order status changes, it will also be returned through this type.
- MYPAY LINK also provides two other types of Callback. When you use these services, you can also use it as a receiving mechanism.
Refund Application Callback: When the system receives the refund application and the refund is processed, MYPAY LINK will send a notification of the refund processing result. Refunds will be based on the support provided by the gold flow service provider, and can be refunded once or multiple times. Therefore, when returning a refund, there will be a separate refund UID to distinguish each refund.
Electronic Invoice Notification Callback: When the order transaction is successful or the refund is successful, if an electronic invoice is issued or invalidated, the status of the electronic invoice will be notified according to the UID of MYPAY LINK. example:
A. When the transaction is successful, an electronic invoice will be issued (the transaction return will be received first, and the electronic invoice will be returned when the electronic invoice is issued)
B. When the refund is successfully initiated, if it is a full refund (refund return [Refund UID] will be received first, and then the electronic invoice will be returned to the original order UID invoice).
C. When the refund is successfully initiated, if it is a partial refund (refund return [Refund UID] will be received first, and then the electronic invoice will be notified, the original order UID invoice will be reported as invalid, and then the electronic invoice information of the refund UID will be reported .)
The following table shows an example of an order and multiple refunds:
Special shop order number | MYPAY LINK UID | Issuing time | Invoice number | Invoice status |
---|---|---|---|---|
201901010001 | Original order UID | 2019-01-01 | AA12345670 | Void |
201901010001 | First partial refund UID | 2019-01-02 | AA12345671 | Void |
201901010001 | Second partial refund UID | 2019-01-03 | AA12345672 | Issuing |
The above electronic invoice time is only within the effective time of issuing the invoice.
When your company receives the data, please take the initiative to return the four characters of the string [8888] to confirm the completion. If your company does not return, the system will send once every 15 minutes and continue for four times. If you still have not received your return confirmation string, the system will stop sending and send a notification letter to your designated mailbox, so that your company can process it immediately Abnormal system connection problem.
The MyPay payment dashboard provides functions such as changing the Callback URL, as well as a test URL mechanism.
The above electronic invoice time is only within the effective time of issuing the invoice.
When your company receives the data, please take the initiative to return the four characters of the string [8888] to confirm the completion. If your company does not return, the system will send once every 15 minutes and continue for four times. If you still have not received your return confirmation string, the system will stop sending and send a notification letter to your designated mailbox, so that your company can process it immediately Abnormal system connection problem.
The MyPay payment dashboard provides functions such as changing the Callback URL, as well as a test URL mechanism.
1. Real-time transaction Callback
When consumers make a transaction, this report will be issued, and the transaction can be completed without leaving the page. When executing the resending transaction in the order management, it will also be sent back through this type.
Real-time transaction Callback parameters:
Parameter | Description |
---|---|
uid | Payment Hub Transaction serial number. |
key | Transaction verification key. |
prc | Transaction Return Code |
cardno | card number/VA/supermarket code |
acode | Bank transaction authorization code |
order_id | The order number of the Guitedian system |
user_id | Consumer account |
cost | Total transaction amount |
currency | Original transaction currency |
actual_cost | Actual transaction amount |
actual_currency | Actual transaction currency |
love_cost | Love donation amount (currency is the same as the actual transaction currency) |
retmsg | Return message |
pfn | Payment Tools |
finishtime | Transaction completion time (YYYYMMDDHHmmss) |
payment_name | The name of the deduction (for regular fixed amount/for regular installment transactions) |
nois | Number of periods (Regular fixed amount / Regular installment transaction only) |
group_id | Regular fixed amount/Regular installment number |
echo_0 | Customized return parameter 1 |
echo_1 | Customized return parameters 2 |
echo_2 | Customized return parameters 3 |
echo_3 | Customized return parameters 4 |
echo_4 | Customized return parameters 5 |
2. Asynchronous transaction Callback
This report is activated for transactions other than the first step, and the page will be left before the transaction can be completed. MYPAY LINK will send a notification when the consumer's payment is completed or the payment time is exceeded.
Asynchronous transaction Callback parameters:
Parameter | Description |
---|---|
uid | Payment Hub Transaction serial number. |
key | Transaction verification key. |
prc | Transaction Return Code |
acode | Bank transaction authorization code |
finishtime | Transaction completion time (YYYYMMDDHHmmss) |
order_id | The order number of the Guitedian system |
user_id | Consumer account |
cost | Total transaction amount |
currency | Original transaction currency |
actual_cost | Actual transaction amount |
actual_currency | Actual transaction currency |
love_cost | Love donation amount (currency is the same as the actual transaction currency) |
retmsg | Return message |
pfn | Payment Tools |
payment_name | The name of the deduction (for regular fixed amount/for regular installment transactions) |
nois | Number of periods (Regular fixed amount / Regular installment transaction only) |
group_id | Regular fixed amount/Regular installment number |
echo_0 | Customized return parameter 1 |
echo_1 | Customized return parameter 2 |
echo_2 | Customized return parameter 3 |
echo_3 | Customized return parameter 4 |
echo_4 | Customized return parameter 5 |
3. Order Confirmation Callback
MYPAY LINK will issue this report when it is unable to know the transaction result in a normal way. MYPAY LINK actively returns transaction results in this transaction return format through active inquiry or reconciliation. When using the query function in the order function, if the order status changes, it will also be returned through this type.
Order confirmation Callback parameters:
Parameter | Description |
---|---|
uid | Payment Hub Transaction serial number. |
key | Transaction verification key. |
prc | Transaction Return Code |
finishtime | Transaction completion time (YYYYMMDDHHmmss) |
order_id | The order number of the Guitedian system |
user_id | Consumer account |
cost | Total transaction amount |
currency | Original transaction currency |
actual_cost | Actual transaction amount |
actual_currency | Actual transaction currency |
love_cost | Love donation amount (currency is the same as the actual transaction currency) |
retmsg | Return message |
pfn | Payment Tools |
payment_name | The name of the deduction (for regular fixed amount/for regular installment transactions) |
nois | Number of periods (Regular fixed amount / Regular installment transaction only) |
group_id | Regular fixed amount/Regular installment number |
echo_0 | Customized return parameter 1 |
echo_1 | Customized return parameters 2 |
echo_2 | Customized return parameters 3 |
echo_3 | Customized return parameters 4 |
echo_4 | Customized return parameters 5 |
4. Refund application Callback
The system receives the refund application, and when the processing is completed, MYPAY LINK will send a notification of the refund processing result. Refunds are based on the support provided by the gold flow service provider, and can be refunded once or multiple times. Therefore, when returning a refund, there is a separate refund UID to distinguish each refund.
Refund application Callback parameters:
Parameter | Description |
---|---|
uid | Payment Hub Transaction serial number. |
key | Transaction verification key. |
prc | Transaction Return Code |
finishtime | Refund processing completion time (YYYYMMDDHHmmss) |
refund_uid | Refund transaction serial number (if refunds are made multiple times, each time will be different; if the refund fails, there will be no such number) |
order_id | The order number of the Guitedian system |
user_id | Consumer account |
cost | refund amount applied for |
currency | currency of refund application |
actual_cost | Actual refund amount |
actual_currency | Actual refund currency |
retmsg | Return message |
pfn | Payment Tools |
payment_name | The name of the deduction (for regular fixed amount/for regular installment transactions) |
nois | Number of periods (Regular fixed amount / Regular installment transaction only) |
group_id | Regular fixed amount/Regular installment number |
refund_type | Refund type (1. Direct online refund 2. Manual refund (credit card type) 3. Manual refund (cash type)) |
expected_refund_date | Estimated refund date (YYYYMMDD) (this date is only available when the refund type is 3) |
echo_0 | Customized return parameter 1 |
echo_1 | Customized return parameter 2 |
echo_2 | Customized return parameter 3 |
echo_3 | Customized return parameter 4 |
echo_4 | Customized return parameter 5 |
5.Electronic Invoice Notification Callback
When the order transaction is successful or the refund is successful, if an electronic invoice is issued or invalidated, the status of the electronic invoice will be notified according to the UID of MYPAY LINK.
Electronic Invoice notification Callback parameters:
Parameter | Description |
---|---|
uid | Payment Hub Transaction serial number. |
key | Transaction verification key. |
prc | Final order status (usually: successful transaction (250,290,600, etc.), refund (230), and partial refund, please refer to Appendix 2) |
order_id | The order number of the Guitedian system |
payment_name | The name of the deduction (for regular fixed amount/for regular installment transactions) |
nois | Number of periods (Regular fixed amount / Regular installment transaction only) |
group_id | Regular fixed amount/Regular installment number |
state | Invoice issuance status 0. Not processed (default) 1 Waiting for processing, 2 Invoice processing is successful 3. Invoice processing failed 4. Invoice |
date | Invoice issuance date (YYYYMMDD) |
wordtrack | Invoice word track |
number | Invoice number |
input_type | Consumer invoice selection type 1. Cloud invoice 2. Invoice donation 3. B2B |
echo_0 | Customized return parameter 1 |
echo_1 | Customized return parameter 2 |
echo_2 | Customized return parameter 3 |
echo_3 | Customized return parameter 4 |
echo_4 | Customized return parameter 5 |
Payment request integration example
Since payment requests require the cooperation of front-end and back-end programs, it is difficult to understand how to use them. So provide a simple interface example. The example gives consumers the operation process as follows:
Assuming that Apache or Nginx has been set up, save the html code of the following link as doc_demo.html and place it under the directory of the Apache or Nginx web page.
doc_demo.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<!-- 在此引入 MYPAY library -->
</head>
<body>
<div class="card text-center">
<div class="card-header">
購物車
</div>
<div class="card-body">
<h5 class="card-title">商品明細</h5>
<img src="https://s3-ap-northeast-1.amazonaws.com/usecase.mypay.static.content.bucket/upload/product/e45db9.jpg?250x250" class="card-img-top" style="height:300px;width:400px" >
</div>
</div>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item active" aria-current="page">付款方式</li>
</ol>
</nav>
<div class="accordion" id="accordionExample">
<div class="card">
<div class="card-header" id="headingOne">
<h2 class="mb-0">
<!-- 消費者按下後顯示銀行選項的按鈕 -->
<button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne" id="VA">
虛擬帳號
</button>
</h2>
</div>
<div id="collapseOne" class="collapse " aria-labelledby="headingOne" data-parent="#accordionExample" >
<!-- 銀行選項顯示 -->
<div class="card-body" id='VA_bank' >
</div>
</div>
</div>
<div class="card">
<div class="card-header" id="headingTwo">
<h2 class="mb-0">
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
信用卡
</button>
</h2>
</div>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordionExample" >
<div class="card-body" id="payment2">
</div>
</div>
</div>
</div>
</div>
<div class="card text-center">
<div class="card-body">
<button type="button" class="btn btn-primary" id="checkout">訂單送出</button>
</div>
</div>
<!-- 使用 MYPAY library 函數的 js file -->
<script src="./doc_demo.js"></script>
</body>
</html>
screen of doc_demo.html :
Include the MYPAY library in the head
Here is the Sandbox environment as an example, please change to the Live environment for production online.
Then add doc_demo.js in the same directory
The operation process includes pressing the virtual account number and displaying the bank. Naturally, the designated html tag displays the bank in the onclick event of the virtual account button.
Remember the id of the virtual account button first:
id is VA. Use the InAppPayment function to display bank options. Let's first look at what the InAppPayment parameters are and how to bring them in. Three parameters, there are a total of 12 fields to be brought in.
- IAPToken: In MYPAY cash flow management system, it has the same page as AES-256 key.
(To obtain the complete AES-256 key, please press the display button of the action)
- IAPPaymentPage : Here is where the bank options are displayed.
This field is brought into'VA_bank'.
StoreType : This example uses a special store to interface, so bring in "store".
Checkout : Here is the button to send the order.
fill with "checkout"。
IsShowInPaymentPage : Decide redirect to MYPAY page to show VA account number, fill with "false"
IsUseStorePage : Decide redirect to MYPAY page to show VA account number, Don't use special store self-designed page. fill with "false"
TotalPrice : Unnecessary use google pay or apple pay. keep null
language : This is an example of a bank selection page, "zh-TW".
currency : currency. "TWD" for use in Taiwan.
errorHandler : Errot Handler function.
finishTransaction : Unnecessary use google pay or apple pay. keep null
EncryptedData : The encrypted string of pfn & store_id with AES-256 encryption method|Require
the sourcecode of doc_demo.js was in right side
AP;
var EncryptedData;
var Is_init = false;
$('#VA').click(function(){
if(Is_init == false){
IAP = InAppPayment({
//IAPToken 替換成貴司自己的
"IAPToken" : "$2y$10$zzhK/pSgmiD2k8wzvaQnwe4//w8.c1g.nAuVLlUtxIyxe",
"EncryptedData": EncryptedData,
"IAPPaymentPage" : "VA_bank" ,
"StoreType" : "store",
"Checkout" : "checkout",
"IsShowInPaymentPage" : "false",
"IsUseStorePage" : "false"
},
{
"language" : "zh-TW" ,
"currency" : "TWD"
},
{
"errorHandler" : show_error
});
Is_init = true;
}
});
function show_error(code,msg){
console.log(code);
console.log(msg);
}
IAP and EncryptedData are placed outside of click because there are other functions that will be used.
Is_init is to prevent consumers from calling InAppPayment every time they click the virtual account option, and only call InAppPayment the first time they press it.
Only difference is EncryptedData, we need a back-end program to generate it. Use php to do this here.
The data to be encrypted are store_uid and pfn. If it is a special store, store_uid is maintained in the basic data maintenance of MYPAY cash flow management system.
For pfn, please refer to Appendix 1: PFN (Payment Instrument) Parameter Table. Here pfn=6. By the way, when pfn only gives a single number, the screens that will appear are credit cards, credit card bonuses, supermarket codes, and virtual account numbers. The buttons will be replaced with google pay and apple pay, and the other screens will not be displayed.
EncryptedData is obtained by encrypting store_uid and pfn with a key, and the php version of the code is on the right.
<?php
//使用貴司自己的AES-256金鑰
$key = "IQBMd2z1iuoc6TkMaWrUSHOuealD";
$size = 16;
//加密 store_uid與pfn的函數
function encrypt($fields, $key)
{
$data = json_encode($fields);
$size = openssl_cipher_iv_length('AES-256-CBC');
$iv = openssl_random_pseudo_bytes($size);
$data = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
$data = base64_encode($iv . $data);
return $data;
}
//回傳 EncryptedData
echo encrypt( array(
'store_uid' => 'L1230411250001',
'pfn' => '6'
) , $key)
?>
Save it as getEncryptedData.php and place it under the current directory.
Next, doc_demo.js needs to get this EncryptedData. Considering that you need to prepare before the consumer clicks on the virtual account, then prepare the EncryptedData when reading the web page. So doc_demo.js adds the following code:
$(document).ready(function(){
$.get("./getEncryptedData.php" , function(Encrypted_data){
EncryptedData = Encrypted_data;
})
});
Next, let's deal with the process after the order is sent. After the consumer presses the order and sends it, it notifies the special store server to initiate a payment request. The server initiates the payment request by the special store server to MYPAY. Use curl in php to accomplish this.
The next step is to prepare the parameters required by the server to initiate a payment request. This example is a special store, so there are three major pieces of data to be transferred by curl: store_uid, service, and encry_data. The first two are very fixed, so only the necessary fields in encry_data are discussed:
- store_uid
EncryptedData has been mentioned, so it is not explained.
- items
For product information, fixed information is given here for the sake of simplicity. In fact, this should be related to the content of the shopping cart.
- cost
The total amount of the order, calculated referring to the item 3 of the transaction information report parameter.
- order_id
The special shop manages the number of each order, and it is recommended not to reuse it.
- user_data
This example is for fixed data. Usually consumer-related information.
- success_returl
This example uses the transaction result page of MYPAY, so this field is blank. If you want to use the self-designed special shop, please bring the redirected URL.
- failure_returl
Description is the same as success_returl, the difference is that this field is forwarded only when the transaction fails.
- trade_token
The object returned by InAppPayment is generated using getTradeToken. Since InAppPayment is a function on the browser side, it needs to be sent to php in some way. This example uses get method to pass.
the sourcecode of server-side PHP payment request was in right side
<?php
// 特約商店商務代號
$storeUid = "L1230411250001";
// 請改成貴司的 AES-256 金鑰
$key = "IQBMd2z1iuoc6TkMaWrUSHOuealD";
//虛擬帳號等候銀行端回應時間較久 , 故 php 執行時間設成5分鐘
ini_set('max_execution_time', 300);
$size = 16;
// 串接資料
$payment = array();
$payment['store_uid'] = $storeUid;
//消費者資訊
$payment['user_data']['user_id'] = "DoSucces";
$payment['user_data']['user_name'] = "金城武";
$payment['user_data']["user_real_name"] = "金城武";
$payment['user_data']["ip"] = "127.0.0.1";
//訂單編號
$payment['order_id'] = "2020020210001";
//訂單總金額
$payment['cost'] = 123;
//訂單使用貨幣別
$payment['currency'] = 'TWD';
//商品資訊
$payment['items'] = [['id' => '1',
'name' => '冰拿鐵',
'cost' => '123',
'amount' => '1',
'total' => '123']];
//tradeToken欄位 , 從 MYPAY library 得到
$payment['trade_token'] = $_GET['tradeToken'];
$payment['success_returl'] = "";
$payment['failure_returl'] = "";
// 加密方法
function encrypt($fields, $key)
{
$data = json_encode($fields);
$size = openssl_cipher_iv_length('AES-256-CBC');
$iv = openssl_random_pseudo_bytes($size);
$data = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
$data = base64_encode($iv . $data);
return $data;
}
// 送出欄位
$postData = array();
$postData['store_uid'] = $storeUid;
$postData['service'] = encrypt(array(
'service_name' => 'api',
'cmd' => 'api/iaptransaction'
), $key);
$postData['encry_data'] = encrypt($payment, $key);
// 資料送出
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, "https://pay.usecase.cc/api/init");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
print_r($result);
?>
Save the code linked above to the current directory and name it transaction.php. The rest is doc_demo.js to make up the onclick event sent by the order and pass the trade_token to transaction.php. The added code is as follows
the sourcecode of doc_demo.js was in right side
var IAP;
var EncryptedData;
var Is_init = false;
//按下虛擬帳號選項後 , 顯示可選銀行
$('#VA').click(function(){
if(Is_init == false){
IAP = InAppPayment({
//IAPToken 替換成貴司自己的
"IAPToken" : "$2y$10$zzhK/pSgmiD2k8wzvaQnwe4//w8.c1g.nAuVLlUtxIyxe/naPKSvS",
"EncryptedData": EncryptedData,
"IAPPaymentPage" : "VA_bank" ,
"StoreType" : "store",
"Checkout" : "checkout",
"IsShowInPaymentPage" : "false",
"IsUseStorePage" : "false"
},
{
"language" : "zh-TW" ,
"currency" : "TWD"
},
{
"errorHandler" : show_error
});
Is_init = true;
}
});
function show_error(code,msg){
console.log(code);
console.log(msg);
}
// 在畫面出現前準備好 EncryptedData
$(document).ready(function(){
$.get("./getEncryptedData.php" , function(Encrypted_data){
EncryptedData = Encrypted_data;
})
});
//訂單送出按下後執行的動作
$('#checkout').click(function(){
let trade_token = {
tradeToken : IAP.getTradeToken()
};
$.get("./transaction.php" , trade_token , function(result){
});
});
Screenshot of the ALL shopping process:
Select the virtual account option
select 第一銀行
click checkout
for sublimt the place order
Appendix 1: PFN (payment instrument) parameter table
There are three ways to set the payment tools that consumers can choose. The first one is the recommended solution:
- All payments: pfn=0, all payment tools that have opened services in the background will be displayed.
- Multiple payment: pfn=1,3,5, only display payment instruments with specific numbers.
- Single payment: pfn=any single number, when pfn=1, payment can only be made by credit card.
The data can be transferred using the number or code. For example: pfn=0 and pfn=all, there will be contracted payment tools, and then you can add payment tools in the background. If you only apply for a credit card at the beginning, it is also recommended to use pfn=0. You can set up any tools you want to add in the future directly through the background.
No | Code | Status | Description |
---|---|---|---|
0 | all | DEV | Consumers choose a payment tool on mypay, it is recommended to implement the function, and then you can set the addition and closing of the transaction tool in the background of the system. The test transaction will need to be carried out |
99 | MobilePayAll | Enabled | If you specify this code, it will be equivalent to specifying three mobile payment methods: ALIPAY, PION, LINEPAYON |
98 | OFFLINE | Disabled | Limited to the direct transaction mode, it automatically distinguishes all offline payment instruments. Currently supported offline payment tools are Pi Wallet, WeCaht Pay, LINE Pay, JKOPay |
1 | CREDITCARD | Enabled | credit card |
2 | RECHARGE | Disabled | transaction with deposit, only support 合庫儲值 |
3 | CSTORECODE | Enabled | payment with convenience store code |
4 | WEBATM | DEV | WEBATM |
5 | TELECOM | Disabled | Telecom micro-payment (telecom bill collection mechanism) |
6 | E_COLLECTION | Enabled | Virtual account number (ATM transfer) |
7 | UNIONPAY | Disabled | UnionPay cards |
8 | SVC | Disabled | Pre-pay cash card(only support GASH ,Imoney) |
9 | ABROAD | Disabled | Overseas credit card (non-Taiwan issued credit card) |
10 | ALIPAY | DEV | Alipay |
11 | SMARTPAY | Disabled | Smart Pay |
12 | MATM | Disabled | Mobile ATM (Bluetooth card reader is required) |
13 | Enabled | WeChat Pay | |
14 | DIRECTDEBIT | Disabled | Periodic deductions |
15 | LINEPAYON | Enabled | LINE online payment (main scan for consumers) |
16 | LINEPAYOFF | Disabled | LINE offline payment (consumers are scanned) |
17 | Disabled | QQ pay | |
18 | QQH5 | Disabled | QQ pay H5 |
19 | WECHATOFF | Disabled | WeChat Pay Offline |
20 | APPLEPAY | Enabled | Apple Pay |
21 | GOOGLEPAY | Enabled | Google Pay |
22 | EACH | Disabled | eACH payment |
23 | C_INSTALLMENT | Disabled | Credit card installment |
24 | C_REDEEM | Enabled | 信用卡紅利 |
25 | CARDLESS | Disabled | Instalment without card (Instalment service provided by financial company) |
26 | COD | DEV | Cash on delivery |
27 | PION | Enabled | Pi wallet online payment (consumer main scan) |
28 | PIOFF | Disabled | Pi takes wallet offline payment (consumers are scanned) |
29 | AMEX | Disabled | American Express |
30 | TAIWANPAY | DEV | Taiwan Pay |
31 | JKOON | Enabled | JKO pay online payment (consumer main scan) |
32 | JKOOF | Disabled | JKO payment offline payment (consumers are scanned) |
Appendix 2: Transaction Status Code
The following status codes returned must be processed to avoid system connection errors. When MYPAY LINK returns, your company’s system cannot read them
Status Code | Status Description | Detailed Description |
---|---|---|
100 | Incorrect data | MYPAYLINK received the data, but the format or data is wrong |
200 | The information is correct | MYPAYLINK receives the correct information and will continue the next transaction |
220 | Cancellation Successful | If the application is cancelled, the cancellation order status is Cancellation Successful |
230 | Refund successful | If you apply for a refund, the status is when the refund is successful. |
250 | Payment successful | In this transaction, the consumer’s payment was successful |
260 | The transaction is successful The payment has not been completed |
Superstore code payment-please wait for the consumer to complete the payment or the consumer abandons the transaction, MYPAY LINK will send another result: 250: the consumer has paid successfully, this is the final result 380: on behalf of If the consumer fails to pay the fee within the time limit, and fails to pay the fee within the time limit, the transaction is deemed to have failed. This is the final result |
265 | Order binding | Indicates that the order number is valid, enter the loan page, but have not yet registered Finally In the return status A0002: The consumer abandons the transaction, and the transaction is deemed to have failed and is the final result. 275: No card installment-please wait for the review to pass |
270 | The transaction is successful The payment has not been completed |
Virtual Account Number-Please wait for the consumer to pay and enter the account After the payment is completed or the consumer abandons the transaction, MYPAY LINK will send another result: 250: The payment is successful on behalf of the consumer. This is the final result 380: It means that the consumer does not pay within the time limit, and if the payment is not made within the time limit, the transaction is deemed to have failed. This is the final result |
275 | Successful transaction Pending review< br>(Approving the loan) |
Instalment without a card-please wait for the review to pass approval or decline, MYPAY LINK will send the result again: 250: It means that the order has been approved, and this is the final result 380: It means that the order has not been reviewed within the time limit, and the transaction is deemed to have failed. This is the final result |
280 | The transaction is successful The payment has not been completed |
Recharge/WEBATM-Online pending payment, waiting status, after the user completes the transaction online, MYPAY LINK will send another result 250: the consumer has paid successfully, this is the final result 300: on behalf of the consumer Payment failed |
290 | The transaction is successful but the information does not match |
The transaction is successful, But the information does not match (including the amount does not match, overdue... etc.), please pay special attention to this type of transaction |
300 | Transaction Failed | The money flow service provider returns the transaction failure or the transaction exceeds the risk control limit rules |
380 | Overdue transaction | Super merchant code or virtual account transaction, exceeding the payment deadline set by the system After verification by MYPAY LINK, there is a chance to change the status 290: Transaction Success, but the information does not match The reason may be caused by loopholes in the service provider’s parameter rules or system time differences |
400 | System error message | If MYPAY LINK or upstream service provider system is abnormal |
600 | Checkout completed | Deemed as payment completed, this status is the status after the upstream service provider confirms the order, which means that the order will be allocated Active inquiry through MYPAY or daily reconciliation mechanism In the operation order function Launch the query function |
A0001 | Transaction pending confirmation | The connection between MYPAY LINK and the cash flow service provider is abnormal. After the query is confirmed, the transaction result will be sent back again. 250: the consumer has indeed completed the payment 600: checkout Complete 300: The money flow service provider returns the transaction failed or exceeds the risk control limit rule transaction |
A0002 | Abandon the transaction | After the screen is directed to MYPAY LINK, the consumer abandons the transaction, and the transaction is deemed to have failed and is the final result |
B200 | Successful execution | Processing successfully executed |
B500 | Execution failed | During processing, data exception will not be processed |
Appendix 3: Setting
- Transaction callback settings
- Transaction key resend and change
Appendix 4: Description of Data Encryption Method
- All fields of HTTPs requests sent to API, the service and encry_data fields are encrypted with AES256+BASE64.
- AES encryption, the format is CBC, the length is 256bits, the key length is 32, the IV length is 16, the transmitted text is the encrypted combined IV and it is transmitted after Base64 conversion.
Method: Use the custom AES256 function to encrypt the JSON data, and then concatenate the IV data with the AES256 encrypted JSON data, and then use base64 to encrypt it into an ASCII string to complete the encryption.
PHP encryption Methods: AesEncrypt -> base64_ecode($IV. $JSON)
C# encryption Methods: AesEncrypt -> (bytes)IV+(bytes)Json -> toBase64
Appendix 5: Support switching language
Support Language Name | Language Code |
---|---|
Traditional Chinese version | zh-TW (default) |
Simplified Chinese | zh-CN |
English | en |
Appendix 6: Credit Card Number for Testing in sandbox environment
The following card numbers only can use in sandbox environment
財金
Gateway
Visa | MasterCard | JCB | |
---|---|---|---|
Card Number | 4907060600015101 | 5409740002370101 | 3567430050009107 |
Effective date | 1220 | 0419 | 0221 |
Security Code | 615 | 106 | 315 |
3D transaction password | fisc1234 | Fisc1234 | Fisc1234 |
National Credit Card Center of R.O.C. Gateway 聯合信用卡中心
(MasterCard/JCB can measure installments and bonuses)
Visa | MasterCard | JCB | |
---|---|---|---|
Card Number | 4938170130000003 | 5430450100001219 | 3560500100001218 |
Effective date | 1228 | 1218 | 1218 |
Security Code | 985 | 214 | 023 |
3D transaction password | nccc1234 |
Appendix 7: Support transaction currency parameters
Currency Parameters | Description |
---|---|
TWD | New Taiwan Dollar |
CNY | Renminbi |
Appendix 8: Support refund payment types
Payment Type | Payment Gateway |
---|---|
Credit Cards | 合庫、玉山、一銀、台灣支付、台北富邦、Acer |
Overseas Credit Cards | 合庫、玉山、一銀、台灣支付、台北富邦、Acer |
UnionPay Card | 合庫、玉山 |
SmartPay | 合庫、一銀 |
Appendix 9: Transaction Types
Code | Name | Description |
---|---|---|
1 | Internet transaction (default) | Payment content entered by consumers |
2 | Physical transactions | When a merchant faces consumers, the merchant enters the payment content to make consumption |
Appendix 10: Domestic credit card issuers
Bank Name | Bank Code | Bank Name | Bank Code | Bank Name | Bank Code |
---|---|---|---|---|---|
土地銀行 | 005 | 合作金庫 | 006 | 第一銀行 | 007 |
華南銀行 | 008 | 彰化銀行 | 009 | 上海銀行 | 011 |
台北富邦 | 012 | 國泰世華 | 013 | 高雄銀行 | 016 |
兆豐銀行 | 017 | 花旗銀行 | 021 | 臺灣企銀 | 050 |
渣打銀行 | 052 | 台中銀行 | 053 | 滙豐銀行 | 081 |
華泰銀行 | 102 | 新光銀行 | 103 | 陽信銀行 | 108 |
三信銀行 | 147 | 聯邦銀行 | 803 | 遠東銀行 | 805 |
元大銀行 | 806 | 永豐銀行 | 807 | 玉山銀行 | 808 |
凱基銀行 | 809 | 星展銀行 | 810 | 台新銀行 | 812 |
日盛銀行 | 815 | 安泰銀行 | 816 | 中國信託 | 822 |
台灣樂天 | 960 | 美國運通 | 975 | 台灣永旺 | 978 |
Appendix 11: Precautions for using Apple Pay voucher
- Use our certificate:
A. A group of our Apple accounts must be provided to join the sandbox.
B. Our MID is merchant.inapp.mypay
- Use your own certificate (hosted):
A. Generate an ECC-256 certificate file based on a Mac computer and send it to our P12 file. In addition, you need to set your own sandbox to avoid actual payment behavior when testing transactions.
Appendix 12: eACH transaction code
Name | Transaction Code | Name | Transaction Code | Name | Transaction Code |
---|---|---|---|---|---|
Charitable donations | 530 | Shopping (non-electronic payment institutions) | 560 | Online shopping refund | 441 |
Instalment | 902 | Security fee | 903 | Payment | 904 |
Cash Value Added | 908 | Rent (Profit) | 909 | Membership Fee (Profit) | 910 |
Intermediary Services | 912 | Loans | 405 | Consumer Loans | 803 |