修改歷程
版本 | 異動日期 | 修訂內容 | 位置 |
---|---|---|---|
1.0 | 2023.11.01 | 新版文件 |
開發前請先閱讀
金鑰的注意事項
Q:金鑰的有效期限
A:MyPay的金鑰有效期限只有一年,如果要延長,請自行至金鑰管理系統延長
Q:金鑰可以在什麼時候延長
A:到期日7天前,都可以延長(不包含第7天),一但超過,系統自動產生新金鑰後,即不可再延長
Q:金鑰即將到期前7天時,系統新發的金鑰是否會於信件中夾帶
A:會
Q:金鑰在到期前何時會發信通知
A:定期發送金鑰到期通知的頻率為:60天/30天/20天,若 貴司皆無動作,則系統會於到期前七天產製新金鑰並發送email到 貴司技術窗口信箱,此時舊的金鑰,因還未過期還可以使用,一旦過期,貴司仍使用舊金鑰則會無法交易
站內付設計概要
設計初衷
該套件的核心目標是將控制權還給電商,讓電商能夠更全面的掌握支付流程以及消費者操作的感受,以實現高度的客製化。這正是我們開發這個套件的初衷,我們深信開發者應該能夠根據其需求和品牌形象來打造自己的支付畫面,以便支付可以更加緊密的整合在電商網站內或APP內交易流程內。
安全性設計
仍保持所有的付費要求發動都僅能從特約商店的網頁伺服器發出請求,透過HTTPS加密傳輸。交易資料不由消費者端送出,可確保資料不被消費者竄改。所有付費資訊經過 MYPAY LINK 匝道進行轉送處理,特約商店不需要處理消費者的付費流程以及安全控管。
資料驗證
交易參數中有一組由雜湊函式運算出的驗証碼,作為資料驗証用,以確保資料正確性。 大部分交易模式,特約商店在原頁面處理付費流程,特約商店只需確保與MYPAY LINK連線正常,即可確保交易安全以及確保資料安全。
系統架構
所有請求與查詢只能透過伺服器發動,由特約商店的網頁伺服器利用伺服端服務程式發動交易,以避免交易資料被消費者竄改或攔截。為確保交易安全,MYPAY LINK 僅能接受 https connection,並注意僅接受TLS1.2以上協定。
MYPAY LINK 目前提供之服務與格式
MYPAY LINK 提供六種資料傳遞與查詢方式,應用情境如下:
(1)付費請求:消費者在特店進行購買商品的當下,特店向系統發動申請請求。
(2)交易查詢:對交易狀況有所疑慮時,可隨時透過交易查詢服務,查看最新訂單狀態。
(3)退款請求:消費者因交易糾紛等情形,申請退款請求後,特店可從後台執行此功能。
(4)取消退款請求:當退款請求還在系統退款柱列等待退款時,可發動此API取消該退款請求。
(5)電子發票查詢:可透過此方法查詢電子發票即時的開立狀態。
(6)交易回報通知:訂單狀態發生變化時,系統會自動傳送回報通知。
※為滿足不同商業模式,我們提供特約商店與經銷商兩種請求方式: 特約商店:使用特約商店網路交易請求參數 經銷商(如網路開店系統商):代特約商店發動,則使用經銷商網路交易請求參數
我們提供介接方式是透過https連線,只接受POST方式傳送交易資料。
- 服務介接之基礎說明:
(特約商店模式) API介接網址 |
測試區 |
https://pay.usecase.cc/api/init |
---|---|---|
正式區 |
https://ka.mypay.tw/api/init |
|
MYPAY library 載入網址 |
測試區 |
https://iap.usecase.cc/plugins/jQuery/jquery-3.3.1.min.js |
https://iap.usecase.cc/InAppPayment.js |
||
正式區 |
https://iap.mypay.tw/plugins/jQuery/jquery-3.3.1.min.js |
|
https://iap.mypay.tw/InAppPayment.js |
||
資料加密方式 |
AES 256編碼 + base64編碼(附錄四 資料加密方式) |
|
加密金鑰 |
金鑰會透過mail發送,也可從管理後台取得 |
|
InAppPaymentToken |
管理後台取得 |
|
文字編碼 |
一律使用UTF-8相容編碼 |
付費請求
消費者在特店進行購買商品的當下,特店向系統發動申請請求,撰寫方式請參考 typescript 範例。
付費請求的流程圖
生命週期
特店網站發動初始化請求
初始化流完成後即可顯示支付工具畫面,並且可以進行付款,開發上建議畫面載入當下就直接進行初始化動作,載入完畢前可事先將root的元素先做隱藏,等到消費者按下付款按鈕再將root元素顯示出來。
// 初始化範例
import paymentBuilder from '@mypay-tw/payment';
import type { Payment } from '@mypay-tw/payment';
const token = '特店或經銷商的 InAppPaymentToken,請登入後端取得';
const storeUid = 'pfn與store_id 被 AES-256 金鑰加密後的密文';
const layer = 'store';
const root = '請輸入您將要顯示支付工具畫面的元素的selector';
const cost = 100; // 交易總金額
paymentBuilder({
token,
storeUid,
layer,
root,
clientUrl: location.href,
language: 'zh-TW',
cost, // 交易總金額
})
.setWhenTradeStartLifeCycle(tradeStart)
.setWhenGotTradeTokenLifeCycle(sendTradeToken)
.setWhenGoToFinishPageLifeCycle(goToFinishPage)
.setWhenTradeFinishLifeCycle(tradeFinish)
.setWhenGotErrorLifeCycle(whenGotError)
.build()
.then((response) => {
console.log('payment init done.', response.getAllPayment());
// 取得
payment.value = response;
console.timeEnd('create payment instance');
});
// 得到交易序號透過後端進行交易
function sendTradeToken(token: string, responseCallback: (code: string) => void) {
console.timeEnd('trade start');
console.log(token);
fetch('電商後端發送交易的API位置!', {
method: 'POST',
body: JSON.stringify({ tradeToken: token })
}).then((response) => {
return response.json();
}).then((result) => {
console.log(result);
responseCallback(result.response.code as string);
console.time('trade finish');
}).catch((err) => {
console.log(err);
responseCallback('error');
console.time('trade finish');
});
}
- 初始化所需參數
欄位 | 型態 | 說明 |
---|---|---|
token | string | 特店或經銷商的 InAppPaymentToken,請登入後端取得 |
storeUid | string | pfn與store_id 被 AES-256 金鑰加密後的密文 |
layer | string | store |
root | string | 顯示支付工具畫面的元素,為 html tag 的 id |
cost | number | 總金額 |
事件名稱 | 對應方法 |
---|---|
當消費者點擊送出交易 | setWhenTradeStartLifeCycle |
當取得交易序號 | setWhenGotTradeTokenLifeCycle |
當交易畫面到達結果頁面上 | setWhenGoToFinishPageLifeCycle |
當交易結束 | setWhenTradeFinishLifeCycle |
當交易發生錯誤 | setWhenGotErrorLifeCycle |
後端產生storeUid
<?php
// 經銷商或特約商店的 AES-256 金鑰
$key = "IQBMd2z1iu6TkMaWrUSHOu";
$size = 16;
// 加密過程
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;
}
// 回傳密文
echo encrypt( array(
'store_uid' => 'L1230411247895',
'pfn' => '3'
) , $key)
?>
欄位 | 型態 | 說明 | 必須 |
---|---|---|---|
store_uid | string | 特約商店編號 | 必要 |
pfn | string | 支付工具 | 必要 |
第二階段確認付款時,由特約商店伺服端發動付費請求
<?php
// 經銷商商務代號
$storeUid = "2891518800047";
// 經銷商金鑰
$key = "AYTid9ACcjGaTK6V3zWmMkyrQS08Ndcx";
// 商品資料
$payment = array();
$payment['store_uid'] = "2891518800047";
$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';
// 加密方法
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'] = $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/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
// 特約商店商務代號
$storeUid = "289151880005";
// 特約商店金鑰
$key = "AYTid9ACcjGaTK6V3zWmMkyrQS08N";
// 商品資料
$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';
// 加密方法
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_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);
?>
/*
java 付費請求的案例 , 共有四個檔案 , 如果要使用請放在同個目錄
*/
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;
}
}
/*
完整範例
https://drive.google.com/file/d/10W8uOXfDzOg4oj_iWPwgC0JicRw3cjRm/view?usp=sharing
*/
/*
總共有五個檔案
除了 Order.cs
其它放在同個目錄下
*/
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; }
}
}
/*
完整範例
https://drive.google.com/file/d/1qMRgQ9wHEuTRGBNa4GULKzzLOK3R3RQG/view?usp=sharing
*/
此交易請求參數內含交易訂單編號,與查詢用之金鑰,以及付費網址。貴司也可將此交易訂單編號綁定貴司的消費者訂單,我們會透過主動回報機制,以POST方式回報交易即時資訊,回報網址可以在管理系統中設定,啟動服務後,系統就會主動回傳訂單狀態。(右邊為經銷商與特約商店介接範例)
特約商店網路交易請求參數
<?php
service :
{
"service_name": "api",
"cmd": "api/iaptransaction"
}
?>
欄位 | 型態 | 說明 |
---|---|---|
store_uid | string(16) | 特約商店商務代號 |
service | JSON | 服務名稱 |
encry_data | text | 交易資訊欄位(JSON格式)加密資料,交易資訊欄位說明請參考下表格-交易資訊回報參數 |
交易資訊回報參數
參數名稱 | 型態 | 說明 | 商品 |
---|---|---|---|
store_uid | string(16) | 特約商店商務代號 | 必要 |
items | array | 商品資訊(請參考下方商品資訊欄位) | 必要 |
cost | int(7) | 訂單總金額 = 物品之總價加總 + 折價 + 運費(如為定期定額交易,此為每一期的應扣金額) | 必要 |
currency | string(3) | 預設交易幣別(如未填寫預設為TWD,可用幣別參數請參考附錄七) | |
order_id | string(50) | 訂單編號(訂單編號最長為50bytes , 建議不要重複使用相同編號) | 必要 |
discount | int(7) | 折價(數值帶負數) | |
shipping_fee | int(7) | 運費 | |
user_data | json object | 消費者資訊(請參考下方消費者資訊欄位) | 必要 |
success_returl | string(200) | 交易成功導頁網址,沒有參數,系統會以後台設定的網址導頁 | |
failure_returl | string(200) | 交易失敗導頁網址,沒有參數,系統會以後台設定的網址導頁 | |
trade_token | string | 開發 setWhenGotTradeTokenLifeCycle 所取得的字串 | 必要 |
echo_0 | string(100) | 自訂回傳參數 1 | |
echo_1 | string(100) | 自訂回傳參數 2 | |
echo_2 | string(100) | 自訂回傳參數 3 | |
echo_3 | string(100) | 自訂回傳參數 4 | |
echo_4 | string(100) | 自訂回傳參數 5 | |
creditcard_is_automatic_payment | string(1) | 0: 手動請款, 1: 自動請款 (default) |
消費者資訊
欄位 | 型態 | 說明 | 必須 |
---|---|---|---|
user_id | string(200) | 該消費者在特店中註冊帳號名稱 | 必要 |
ip | string(15) | 消費者網際網路來源 IP | 必要 |
user_name | string(100) | 消費者姓名 | 必要 |
user_real_name | string(100) | 消費者真實姓名 | 必要 |
user_address | string(100) | 消費者地址 | 必要 |
user_sn_type | int(1) | 1:身分證,2:統一證號,3:護照號碼 (消費者是本國人為1,外國人2 or 3) | |
user_sn | string(16) | 消費者身份證字號/統一證號/護照號碼 | |
user_phone | int(16) | 消費者家用電話(白天電話) | |
user_cellphone_code | string(3) | 消費者行動電話國碼(預設886) | |
user_cellphone | int(16) | 消費者行動電話 | 必要 |
user_email | string(100) | 消費者 E-Mail | 必要 |
user_birthday | string(8) | 消費者生日(格式為 YYYYMMDD,如 20090916) |
商品資訊
欄位 | 型態 | 說明 | 必須 |
---|---|---|---|
id | string(20) | 商品編號 | 必要 |
name | string(20) | 商品名稱 | 必要 |
cost | string(10) | 商品單價 | 必要 |
amount | string(10) | 商品數量 | 必要 |
total | string(20) | 商品小計 | 必要 |
回傳資料 (JSON格式)
欄位 | 說明 |
---|---|
key | 交易驗証碼 查詢交易時會用到此參數 |
uid | Payment Hub 之交易流水號 查詢交易時會用到此參數 |
code | 交易回傳碼 |
cardno | 銀行端口回傳碼 |
acode | 銀行交易授權碼 |
order_id | 貴特店系統的訂單編號 |
user_id | 消費者帳號 |
cost | 總交易金額 |
currency | 原交易幣別 |
actual_cost | 實際交易金額 |
actual_currency | 實際交易幣別 |
pfn | 付費方法 |
finishtime | 交易完成時間(YYYYMMDDHHmmss) |
msg | 回傳訊息 |
echo_0 | 自訂回傳參數 1 |
echo_1 | 自訂回傳參數 2 |
echo_2 | 自訂回傳參數 3 |
echo_3 | 自訂回傳參數 4 |
echo_4 | 自訂回傳參數 5 |
result_type | 支付方式CSTORECODE(超商代碼)和E_COLLECTION(虛擬帳號)有效 result_content的格式:1 Url 2 Html 3 Xml 4 Json 5 Csv 6 Stream |
result_content | 支付方式CSTORECODE(超商代碼)和E_COLLECTION(虛擬帳號)有效,欄位說明請參考下方result_content說明 |
result_content說明
E_COLLECTION(虛擬帳號)
欄位 | 說明 |
---|---|
LimitExpiredDate | 繳費期限 |
BankCode | 銀行代碼 |
SourceCode | 繳費代碼 |
BusinessName | 帳戶名稱 |
Cost | 繳費金額 |
CSTORECODE(超商代碼)
欄位 | 說明 |
---|---|
StoreCode | 超商代碼;目前有FAMIPORT、IBON、LIFEET |
ImageCode | 條碼類型;BARCODE-C39和QRCODE |
ResultCode | JSON格式; PinCode:繳費代碼(此代碼可以至超商設備輸入後列印繳費) BarCode1:第一列Barcode碼 BarCode2:第二列Barcode碼 BarCode3:第三列Barcode碼 條碼類型:BARCODE-C39(FAMIPORT、LIFEET適用) 需顯示三列條碼圖供超商掃描:BarCode1、BarCode2、BarCode3 條碼類型:QRCODE(IBON適用) 需顯示QRCODE,內容為PinCode碼。 |
BusinessName | 廠商代碼 |
Cost | 繳費金額 |
LimitExpiredDate | 繳費期限 |
交易查詢
<?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);
?>
系統通知交易結果異常,貴司而無法正常接收訂單時,可以透過我們提供的交易結果查詢服務,自行更新訂單狀態,以確保交易結果正確。 符合查詢規則時,則會回傳相關交易欄位,不符合查詢條件則回傳原查詢欄位。須符合條件才會回傳正確的查詢結果,交易查詢除了提供單筆查詢,也提供一次多筆查詢。
特約商店交易查詢參數說明
<?php
service :
{
"service_name": "api",
"cmd": "api/queryorder"
}
?>
欄位 | 說明 |
---|---|
store_uid | 特約商店商務代號 |
service | text |
encry_data | text |
『交易查詢』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
uid | string | Payment Hub之交易流水號 | |
key | string | 交易驗証碼 | |
prc | string | 主要交易回傳碼(retcode) | |
finishtime | string | 交易完成時間(YYYYMMDDHHmmss) | |
cardno | string | 銀行端口回傳碼 | |
acode | string | 授權碼 | |
issuing_bank | string | 發卡行 | |
issuing_bank_uid | string | 發卡銀行代碼 | |
is_agent_charge | int | 是否為經銷商代收費模式 | 『是否為經銷商代收費模式』值參考 |
transaction_mode | integer | 交易服務類型 | 『交易服務類型』值參考 |
supplier_name | string | 交易之金融服務商 | |
supplier_code | string | 交易之金融服務商代碼 | 『金流供應商代碼』值參考 |
order_id | string | 貴特店系統的訂單編號 | |
user_id | string | 消費者帳號 | |
cost | string | 總交易金額 | |
currency | string | 原交易幣別 | |
actual_cost | string | 實際交易金額 | |
actual_currency | string | 實際交易幣別 | |
price | string | 請求交易點數/金額 | |
actual_price | string | 實際交易點數/金額 | |
recharge_code | string | 交易產品代碼 | |
love_cost | string | 愛心捐款金額 | |
retmsg | string | 回傳訊息 | |
pfn | string | 付費方法 | |
trans_type | string | 付款種類 | 『交易類型定義』值參考 |
redeem | string | 紅利資訊 JSON 格式 | 『紅利資訊』值參考 |
installment | string | 信用卡分期資訊 JSON 格式 | 『分期資訊』值參考 |
payment_name | string | 定期定額式/定期分期式扣款名稱 | |
nois | string | 定期定額式/定期分期式扣繳期數 | |
group_id | string | 1.定期定額式扣款編號 2.定期分期式扣款編號 |
|
bank_id | string | 虛擬帳號銀行代碼 | |
expired_date | string | 有效日期(YYYYMMDDHHmmss) 虛擬帳號、超商代碼、無卡分期資訊 |
|
appropriation_date | string | 預計撥款日期(YYYYMMDD) | |
result_type | integer | 虛擬帳號、超商代碼 資料格式類型 | 『閘道內容回傳格式類型』值參考 |
result_content_type | string | 資料內容所屬支付名稱 | 『資料內容所屬支付名稱』值參考 |
result_content | string | 虛擬帳號、超商代碼 資料內容 | 『虛擬帳號回傳欄位』值參考 『ibon』值參考 『FamiPort』值參考 『Life-ET』值參考 |
refund_order | array | 退款訂單資訊(多筆格式) | 每筆『交易查詢-退款資訊』欄位參考 |
cancel_order | array | 取消訂單資訊(多筆格式) | 每筆『交易查詢-取消資訊』欄位參考 |
invoice_state | integer | 發票開立狀態 | 『電子發票開立狀態類型』值參考 |
invoice_date | string | 發票開立日期(YYYYMMDD) | |
invoice_wordtrack | string | 發票字軌 | |
invoice_number | string | 發票號碼 | |
invoice_rand_code | string | 電子發票隨機碼 | |
invoice_seller_ban | string | 賣方統一編號 | |
invoice_buyer_ban | string | 買方統一編號 | |
invoice_left_qrcode | string | 電子發票左邊QrCode內容 | |
invoice_middle_barcode | string | 電子發票中間Barcode內容(格式Code-39) | |
invoice_right_qrcode | string | 電子發票右邊QrCode內容 | |
invoice_title_type | integer | 電子發票列印標題格式 | 『電子發票紙本列印標題類型』值參考 |
invoice_title | integer | 電子發票列印標題格式 | 『電子發票紙本列印標題類型』值參考 |
invoice_print_type | integer | 電子發票列印類型 | 『電子發票列印類型』值參考 |
invoice_print_device | integer | 電子發票列印設備 | 『電子發票列印設備』值參考 |
invoice_amount | string | 電子發票銷售總額 | |
invoice_sales_amount | string | 電子發票銷售額 | |
invoice_tax_amount | string | 電子發票稅額 | |
invoice_order_detail | string | 電子發票全部產品明細(JSON格式) | 『商品細項』值參考 |
invoice_ratetype | integer | 電子發票稅率別 | 『電子發票稅率別』值參考 |
invoice_input_type | integer | 電子發票開立類型 | 『電子發票開立類型』值參考 |
invoice_allowance | array | 電子發票折讓資訊 | 每筆『電子發票折讓資訊』欄位參考 |
items | array | 訂單商品項目 | 每筆『商品項目』欄位參考 |
echo_0 | string | 自訂回傳參數 1 | |
echo_1 | string | 自訂回傳參數 2 | |
echo_2 | string | 自訂回傳參數 3 | |
echo_3 | string | 自訂回傳參數 4 | |
echo_4 | string | 自訂回傳參數 5 |
回傳資料(JSON格式)
欄位 | 說明 |
---|---|
key | 交易驗証碼 |
uid | MYPAY LINK之交易流水號 |
prc | 交易回傳碼 |
cardno | 卡號/VA/超商代碼 |
acode | 銀行交易授權碼/虛擬帳號/超商代碼 |
order_id | 貴特店系統的訂單編號 |
user_id | 消費者帳號 |
cost | 總交易金額 |
currency | 原交易幣別 |
actual_cost | 實際交易金額 |
actual_currency | 實際交易幣別 |
love_cost | 愛心捐款金額(幣別同實際交易幣別) |
retmsg | 回傳訊息 |
pfn | 付費方法 |
finishtime | 交易完成時間(YYYYMMDDHHmmss) |
bank_id | VA繳費銀行代碼(虛擬帳號) |
expired_date | 有效日期(虛擬帳號或超商代碼) |
invoice_state | 發票開立狀態 |
invoice_date | 發票開立日期(YYYYMMDD) |
invoice_wordtrack | 發票字軌 |
invoice_number | 發票號碼 |
invoice_input_type | 消費者發票選擇類型 |
refund_order | 非必回傳欄位,欄位型態內容為陣列。 查詢訂單時,若有發動過退款一次或多次成功,則此內容則含所有退款成功之退款訂單資訊。 |
cancel_order | 非必回傳欄位,欄位型態內容為陣列。 查詢訂單時,若有發動過取消訂單一次或多次成功,則此內容則含所有取消訂單成功之取消訂單資訊。 |
echo_0 | 自訂回傳參數 1 |
echo_1 | 自訂回傳參數 2 |
echo_2 | 自訂回傳參數 3 |
echo_3 | 自訂回傳參數 4 |
echo_4 | 自訂回傳參數 5 |
result_type | 支付方式CSTORECODE(超商代碼)和E_COLLECTION(虛擬帳號)有效 result_content的格式: 1 Url 2 Html 3 Xml 4 Json 5 Csv 6 Stream |
result_content | 支付方式CSTORECODE(超商代碼)和E_COLLECTION(虛擬帳號)有效,欄位說明請參考上方交易result_content說明 |
退款請求
<?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);
?>
若需要退款時,發動此API提出退款請求。此退款請求將會暫時保留在系統退款柱列中,隔天凌晨起處理退款作業。可退款訂單為依據該筆訂單交易方式,請參考附錄八。
特約商店退款請求參數說明
<?php
service :
{
"service_name": "api",
"cmd": "api/refund"
}
?>
欄位 | 說明 |
---|---|
store_uid | 特約商店商務代號 |
service | {"service_name": "api", "cmd": "api\/refund"} JSON格式,AES256加密資料 |
encry_data | 『交易退款』欄位參考 JSON格式,AES256加密資料 |
『交易退款』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
store_uid | string | 特約商店代碼 | |
key | string | 交易驗証碼 | |
uid | string | 訂單編號(UID) | |
cost | string | 退款金額(可部分退款) | |
invoice_state | integer | 若有開立電子發票,指定電子發票使用作廢或折讓 注意:跨發票月份無法作廢 |
『電子發票退款時使用作廢或折讓』值參考 |
items | array | 退款項目 若使用電子發票,此欄位必填 退款項目之項目名稱必須和交易時之產品項目名稱相同 退款項目之總金額必須與退款金額一致 |
每筆『商品項目』欄位參考 |
『交易退款』回傳欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
key | string | 特約商店驗證碼 (store_token) | |
uid | string | 訂單編號(UID) | |
code | string | 處理狀態 B200 或 B500 | |
msg | string | 回傳訊息 | |
row_data | object | 退款資訊(即時退款才有此資訊) | 『退款完成回傳資訊』欄位參考 |
取消退款請求
<?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);
?>
當天發動退款請求時,會在系統退款柱列等待退款。系統退款時間為隔天凌晨零時才發動退款,故在尚未做退款作業前,可發動此API請求,來取消(5)退款請求(也可透過管理介面來取消)。
特約商店取消退款請求參數說明
<?php
service :
{
"service_name": "api",
"cmd": "api/refundcancel"
}
?>
欄位 | 說明 |
---|---|
store_uid | 特約商店商務代號 |
service | text |
encry_data | text |
『取消退款』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
store_uid | string | 特約商店編號(金鑰中心會驗證) | |
key | string | 特約商店驗證碼 (store_token) | |
uid | string | 訂單編號(UID) | |
rows | array | 資料若多筆,則以此欄位判別 |
『取消退款』回傳欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
key | string | 特約商店驗證碼 (store_token) | |
uid | string | 訂單編號(UID) | |
code | string | 處理狀態 B200 或 B500 | |
msg | string | 回傳訊息 | |
row_data | object | 退款資訊(即時退款才有此資訊) | 『退款完成回傳資訊』欄位參考 |
電子發票查詢
如您有申請透過MYPAY使用電子發票,則可以透過此方法查詢目前電子發票即時的開立狀態,而交易查詢則包含訂單完整資訊。您可以依您需求作個別查詢。符合查詢規則時,則會回傳相關交易欄位,不符合查詢條件則回傳原查詢欄位。須符合條件才會回傳正確的查詢結果,交易查詢除了提供單筆查詢,也提供一次多筆查詢。
特約商店電子發票參數說明
<?php
service :
{
"service_name": "api",
"cmd": "api/invoice"
}
?>
欄位 | 說明 |
---|---|
store_uid | 特約商店商務代號 |
service | text |
encry_data | text |
『電子發票查詢』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
uid | string | 訂單 uid | |
key | string | 查詢驗證碼 |
『電子發票查詢』回傳欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
uid | string | 原MYPAYLINK 之交易流水號 | |
key | string | 交易驗証碼 | |
prc | string | 主要交易回傳碼(retcode) | |
order_id | string | 貴特店系統的訂單編號 | |
cost | string | 交易金額 | |
currency | string | 交易幣別 | |
actual_cost | string | 實際交易金額 | |
actual_currency | string | 實際交易幣別 | |
state | string | 發票開立狀態 0.不處理(預設) 1等候處理中,2發票處理成功 3.發票處理失敗 4.作癈 5.系統服務異常 6.折讓 |
|
date | string | 發票開立日期(YYYYMMDD) | |
wordtrack | string | 發票字軌 | |
number | string | 發票號碼 | |
rand_code | string | 隨機碼 | |
seller_ban | string | 賣方統編 | |
buyer_ban | string | 買方統編 | |
left_qrcode | string | 左邊QrCode(電子發票查詢碼) | |
middle_barcode | string | 中間Barcode (Code-39格式) | |
right_qrcode | string | 右邊QrCode(電子發票產品資訊-精簡版) | |
title_type | integer | 電子發票列印標題格式 | 『電子發票紙本列印標題類型』值參考 |
title | string | 電子發票標題內容 | |
print_type | integer | 電子發票列印類型 | 『電子發票列印類型』值參考 |
print_device | integer | 電子發票列印設備 | 『電子發票列印設備』值參考 |
amount | string | 電子發票開立總額 | |
sales_amount | string | 電子發票銷售額 | |
tax_amount | string | 電子發票稅額 | |
order_detail | string | 電子發票開立之產品詳細資訊(JSON格式) | 『商品細項』值參考 |
ratetype | integer | 電子發票稅率別 | 『電子發票稅率別』值參考 |
input_type | integer | 電子發票開立類型 | 『電子發票開立類型』值參考 |
cloud_type | string | 電子發票開立類型-雲端發票類型 | 『雲端發票類型』值參考 |
mobile_code | string | 當cloud_type為2時紀錄的手機條碼 | |
tax_id | string | 當cloud_type為2時紀錄的統一編號 | |
natural_person | string | 當cloud_type為3時紀錄的自然人憑證條碼 | |
m_post_zone | string | 當cloud_type為4時紀錄中獎時紙本發票郵遞區號 | |
m_address | string | 當cloud_type為4時紀錄中獎時紙本發票收件住址 | |
love_code | string | 當input_type為2時紀錄的愛心碼 | |
b2b_title | string | 當input_type為3時紀錄的發票抬頭 | |
b2b_id | string | 當input_type為3時紀錄的統一編號 | |
b2b_post_zone | string | 當input_type為3時紀錄的郵遞區號 | |
b2b_address | string | 當input_type為3時紀錄的發票地址 | |
allowance | array | 電子發票折讓資訊 | 每筆『電子發票折讓資訊』欄位參考 |
group_id | string | 1.定期定額式扣款編號 2.定期分期式扣款編號 |
|
payment_name | string | 定期定額式/定期分期式扣款名稱 | |
nois | string | 定期定額式/定期分期式扣繳期數 | |
echo_0 | string | 自訂回傳參數 1 | |
echo_1 | string | 自訂回傳參數 2 | |
echo_2 | string | 自訂回傳參數 3 | |
echo_3 | string | 自訂回傳參數 4 | |
echo_4 | string | 自訂回傳參數 5 |
交易回傳格式
<?php
//取得回傳內容
$result = $_REQUEST;
//使用key與'uid驗證,$db[ 'key']與$db[ 'uid']為交易請求回傳欄位
//驗證資料來源
if ($result['key'] == $db[ 'key'] && $result['uid'] == $db[ 'uid']){
print("8888");
}
?>
您可在管理介面設定回報網址,系統會進行交易回報通知。 系統會主動通知系統設定之回報網址,若貴司系統接到回報後,沒有回傳確認,系統會每隔五分鐘通知一次,會進行連續四次通知,若仍然沒有回覆,將不再通知,但會寄送e-mail到技術人員信箱或指定信箱以利您後續處理。
- MYPAY LINK 提供三種回報類型: 這三種類型,MYPAY LINK 確認有這三個接收機制,才會開放系統上線。
即時交易回報:消費者支付,不需要離開 MYPAY LINK 頁面即可完成交易。 使用訂單管理內的重送交易,也會透過此類型回傳。
非即時交易回報:消費者支付,會離開 MYPAY LINK 頁面,方可完成交易。 當消費者繳完費用或超過繳費時間,MYPAY LINK 會發送通知。
訂單確認回報:MYPAY LINK 無法以正常方式得知交易結果。當 MYPAY LINK 透過主動查詢或對帳等方式得知交易結果,以此交易回傳格式,主動回傳交易結果。當使用訂單功能內發動查詢功能,若訂單狀態有變更,也會透過此類型回傳。
- MYPAY LINK 也提供另二種回報類型,當您有使用這些服務時,也可以做接收機制。
退款申請回報:當系統接收退款申請後,而處理退款完畢時,MYPAY LINK 會發送退款處理結果通知。退款會依據金流服務商提供支援,可退一次/多次,故回報退款時,將有獨立的退款UID,用以區別各次退款。
電子發票通知回報:當訂單交易成功,或退款成功時,若有進行電子發票的開立或作廢,會依照 MYPAY LINK 的UID進行通報電子發票狀態。例:
A、當交易成功後,會進行電子發票開立(會先收到交易回報,等電子發票開立完成時,電子發票進行回報)
B、發動退款成功時,如果為全額退款(會先收到退款回報[退款UID],而之後電子發票會進行原訂單UID發票作廢回報)。
C、發動退款成功時,如果為部分退款(會先收到退款回報[退款UID],而之後電子發票通知,會回報原訂單UID發票作廢,接著回報退款UID的電子發票資訊。)
下表格為一筆訂單且多次退款範例示意:
特店訂單編號 | MYPAY LINK 的UID | 開立時間 | 發票號碼 | 發票狀態 |
---|---|---|---|---|
201901010001 | 原訂單UID | 2019-01-01 | AA12345670 | 作廢 |
201901010001 | 第一次部分退款UID | 2019-01-02 | AA12345671 | 作廢 |
201901010001 | 第二次部分退款UID | 2019-01-03 | AA12345672 | 開立 |
以上電子發票時間僅在開立發票有效時間內。
貴司接收到資料時,請主動回傳字串【8888】四個字元,確認完成。若貴司沒有回傳,系統會間隔十五分鐘傳送一次持續四次,若仍未接受到貴司回傳確認字串,系統即會停止傳送,並發通知信到貴司指定信箱,以利貴司可即時處理系統連線異常問題。
後台管理有提供變更接收網址等功能,也提供測試網址機制。
以上電子發票時間僅在開立發票有效時間內。
貴司接收到資料時,請主動回傳字串【8888】四個字元,確認完成。若貴司沒有回傳,系統會間隔十五分鐘傳送一次持續四次,若仍未接受到貴司回傳確認字串,系統即會停止傳送,並發通知信到貴司指定信箱,以利貴司可即時處理系統連線異常問題。
後台管理有提供變更接收網址等功能,也提供測試網址機制。
即時交易回報
消費者進行交易時,會發動此回報,不需要離開頁面即可完成交易。 執行訂單管理內的重送交易時,也會透過此類型回傳。
即時交易回報參數:
欄位 | 說明 |
---|---|
key | 交易驗証碼 |
prc | 交易回傳碼 |
cardno | 卡號/VA/超商代碼 |
acode | 銀行交易授權碼 |
order_id | 貴特店系統的訂單編號 |
user_id | 消費者帳號 |
uid | MYPAY LINK之交易流水號 |
cost | 總交易金額 |
currency | 原交易幣別 |
actual_cost | 實際交易金額 |
actual_currency | 實際交易幣別 |
love_cost | 愛心捐款金額(幣別同實際交易幣別) |
retmsg | 回傳訊息 |
pfn | 支付工具 |
finishtime | 交易完成時間(YYYYMMDDHHmmss) |
payment_name | 扣款名稱(定期定額/定期分期交易專用) |
nois | 期數 (定期定額/定期分期交易專用) |
group_id | 定期定額/定期分期編號 |
echo_0 | 自訂回傳參數 1 |
echo_1 | 自訂回傳參數 2 |
echo_2 | 自訂回傳參數 3 |
echo_3 | 自訂回傳參數 4 |
echo_4 | 自訂回傳參數 5 |
2.非即時交易回報
在非第一階段的交易都發動此回報,會離開頁面,方可完成交易。 當消費者繳費完成、或超過繳費時間,MYPAY LINK 會發送通知。
非即時交易回報參數:
欄位 | 說明 |
---|---|
key | 交易驗証碼 |
prc | 交易回傳碼 |
acode | 銀行交易授權碼 |
finishtime | 交易完成時間(YYYYMMDDHHmmss) |
uid | MYPAY LINK 交易流水號 |
order_id | 貴特店系統的訂單編號 |
user_id | 消費者帳號 |
cost | 總交易金額 |
currency | 原交易幣別 |
actual_cost | 實際交易金額 |
actual_currency | 實際交易幣別 |
love_cost | 愛心捐款金額(幣別同實際交易幣別) |
retmsg | 回傳訊息 |
pfn | 支付工具 |
payment_name | 扣款名稱(定期定額/定期分期交易專用) |
nois | 期數 (定期定額/定期分期交易專用) |
group_id | 定期定額/定期分期編號 |
echo_0 | 自訂回傳參數 1 |
echo_1 | 自訂回傳參數 2 |
echo_2 | 自訂回傳參數 3 |
echo_3 | 自訂回傳參數 4 |
echo_4 | 自訂回傳參數 5 |
3.訂單確認回報
MYPAY LINK 無法以正常方式得知交易結果時,發動此回報。MYPAY LINK 透過主動查詢或對帳等方式,以此交易回傳格式,主動回傳交易結果。當使用訂單功能內發動查詢功能,若訂單狀態有變更,也會透過此類型回傳。
訂單確認回報參數:
欄位 | 說明 |
---|---|
key | 交易驗証碼 |
prc | 交易回傳碼 |
finishtime | 交易完成時間(YYYYMMDDHHmmss) |
uid | MYPAYLINK 之交易流水號 |
order_id | 貴特店系統的訂單編號 |
user_id | 消費者帳號 |
cost | 總交易金額 |
currency | 原交易幣別 |
actual_cost | 實際交易金額 |
actual_currency | 實際交易幣別 |
love_cost | 愛心捐款金額(幣別同實際交易幣別) |
retmsg | 回傳訊息 |
pfn | 支付工具 |
payment_name | 扣款名稱(定期定額/定期分期交易專用) |
nois | 期數 (定期定額/定期分期交易專用) |
group_id | 定期定額/定期分期編號 |
echo_0 | 自訂回傳參數 1 |
echo_1 | 自訂回傳參數 2 |
echo_2 | 自訂回傳參數 3 |
echo_3 | 自訂回傳參數 4 |
echo_4 | 自訂回傳參數 5 |
4.退款申請回報
系統接收到退款申請,處理完畢時,MYPAY LINK 會發送退款處理結果通知。退款依據金流服務商提供支援,可退一次/多次,故回報退款時,有獨立的退款UID,以區別各退款。
退款結果回傳格式 :
欄位 | 說明 |
---|---|
key | 交易驗証碼 |
prc | 交易回傳碼 |
finishtime | 退款處理完成時間(YYYYMMDDHHmmss) |
uid | 原MYPAYLINK 之交易流水號 |
refund_uid | 退款之交易流水號(若多次退款,每次皆會不同;退款失敗則無此編號) |
order_id | 貴特店系統的訂單編號 |
user_id | 消費者帳號 |
cost | 申請之退款金額 |
currency | 申請之退款幣別 |
actual_cost | 實際退款金額 |
actual_currency | 實際退款幣別 |
retmsg | 回傳訊息 |
pfn | 支付工具 |
payment_name | 扣款名稱(定期定額/定期分期交易專用) |
nois | 期數 (定期定額/定期分期交易專用) |
group_id | 定期定額/定期分期編號 |
refund_type | 退款類型(1.直接線上退款 2.手動退款(信用卡類) 3.手動退款(現金類)) |
expected_refund_date | 預計退款日(YYYYMMDD)(退款類型為3時,才有此日期) |
echo_0 | 自訂回傳參數 1 |
echo_1 | 自訂回傳參數 2 |
echo_2 | 自訂回傳參數 3 |
echo_3 | 自訂回傳參數 4 |
echo_4 | 自訂回傳參數 5 |
5.電子發票通知回報
當訂單交易成功、或退款成功時,若有進行電子發票的開立或作廢,會依照 MYPAY LINK 的UID進行通報電子發票狀態。
電子發票通知回傳格式 :
欄位 | 說明 |
---|---|
uid | MYPAY LINK之交易流水號 |
key | 交易驗証碼 |
prc | 最終訂單狀態(通常為:交易成功(250,290,600等)、退款(230)、以及部分退款,請參閱附錄二) |
order_id | 貴特店系統的訂單編號 |
payment_name | 扣款名稱(定期定額/定期分期交易專用) |
nois | 期數 (定期定額/定期分期交易專用) |
group_id | 定期定額/定期分期編號 |
state | 發票開立狀態 0.不處理(預設) 1等候處理中,2發票處理成功 3.發票處理失敗 4.作癈 |
date | 發票開立日期(YYYYMMDD) |
wordtrack | 發票字軌 |
number | 發票號碼 |
input_type | 消費者發票選擇類型 1.雲端發票 2.發票捐贈 3.B2B |
echo_0 | 自訂回傳參數 1 |
echo_1 | 自訂回傳參數 2 |
echo_2 | 自訂回傳參數 3 |
echo_3 | 自訂回傳參數 4 |
echo_4 | 自訂回傳參數 5 |
<?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)
?>
接下來來處理訂單送出後的流程。消費者按下訂單送出後,通知特店 server 發動付費請求。 server 發動付費請求是特店 server 向 MYPAY 發動的,在 php 使用 curl 完成這件事。
接下來要準備 server 端發動付費請求所需的參數。此範例是特店,所以 curl 要傳的資料有三大塊 : store_uid、service 和 encry_data。前兩個很固定,所以只討論 encry_data 中必要的欄位 :
- store_uid
EncryptedData 提到過,所以不做說明。
items
商品資訊,簡單起見這邊給予固定的資料,實際上這應該跟購物車的內容有關。
cost
訂單總金額,計算參考交易資訊回報參數的項次3。
order_id
特店管理每筆訂單的編號,建議不要重複使用。
user_data
此範例是給固定的資料。通常是消費者相關的資料。
success_returl
此範例是使用 MYPAY 的交易結果頁,所以此欄位為空。如果要使用特店自行設計的, 請帶入轉導的網址。
failure_returl
說明同 success_returl,差別是交易失敗時才轉導此欄位。
trade_token
由setWhenGotTradeTokenLifeCycle產生的。 基本上就是由瀏覽器上發動,此範例使用 get method 傳遞。
於是整個 server 發動付費請求的 php code 如右
<?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);
?>
將以上連結的 code 儲存到目前目錄並命名為 transaction.php。
附錄一:PFN(支付工具)參數表
設定消費者可選擇的支付工具有哪些,設定方式有三種,第一種為建議方案:
- 所有支付:pfn=0,後台有開啟服務的支付工具都會顯示。
- 多種支付:pfn=1,3,5,只顯示特定幾種編號的支付工具。
- 單一支付:pfn=任單一編號,當pfn=1則僅能透過信用卡支付。
資料傳遞可使用編號也可以使用代碼 。 例如:pfn=0跟pfn=all,一樣都會出現簽約的支付工具,之後可以在後台增加支付工具。 若一開始只有申請信用卡,也建議使用pfn=0,日後欲新增任何工具都可直接透過後台設定。
編號 | 代碼 | 狀態 | 說明 |
---|---|---|---|
0 | all | 開發 | 消費者在mypay 選擇支付工具,建議實作功能即可,之後可在系統後台設定交易工具的新增與關閉 測試交易會需要進行 |
99 | MobilePayAll | 啟用 | 若指定此代碼,將等同於指定使用ALIPAY,PION, LINEPAYON三種行動支付方式 |
98 | OFFLINE | 停用 | 限定在直接交易模式下,自動判別所有線下支付工具。目前支援之線下支付工具為Pi 拍錢包、WeCaht Pay、LINE Pay、JKOPay |
1 | CREDITCARD | 啟用 | 信用卡 |
2 | RECHARGE | 停用 | 儲值交易,目前只有合庫儲值 |
3 | CSTORECODE | 啟用 | 超商代碼 |
4 | WEBATM | 開發 | WEBATM |
5 | TELECOM | 停用 | 電信小額付款(電信帳單代收機制) |
6 | E_COLLECTION | 啟用 | 虛擬帳號 (ATM轉帳) |
7 | UNIONPAY | 停用 | 銀聯卡 |
8 | SVC | 停用 | 點數卡(目前有GASH ,Imoney) |
9 | ABROAD | 停用 | 海外信用卡(非台灣發行信用卡) |
10 | ALIPAY | 開發 | 支付寶 |
11 | SMARTPAY | 停用 | Smart Pay |
12 | MATM | 停用 | 行動ATM(需要有藍牙讀卡機) |
13 | 啟用 | 微信支付 | |
14 | DIRECTDEBIT | 停用 | 定期扣款 |
15 | LINEPAYON | 啟用 | LINE線上付款(消費者主掃) |
16 | LINEPAYOFF | 停用 | LINE線下付款(消費者被掃) |
17 | 停用 | QQ支付 | |
18 | QQH5 | 停用 | QQ支付H5 |
19 | WECHATOFF | 停用 | 微信支付線下 |
20 | APPLEPAY | 啟用 | Apple Pay |
21 | GOOGLEPAY | 啟用 | Google Pay |
22 | EACH | 停用 | eACH交易 |
23 | C_INSTALLMENT | 停用 | 信用卡分期 |
24 | C_REDEEM | 啟用 | 信用卡紅利 |
25 | CARDLESS | 停用 | 無卡分期(由資融公司提供分期服務) |
26 | COD | 開發 | 貨到付款 |
27 | PION | 啟用 | Pi 拍錢包線上付款(消費者主掃) |
28 | PIOFF | 停用 | Pi 拍錢包線下付款(消費者被掃) |
29 | AMEX | 停用 | 美國運通 |
30 | TAIWANPAY | 開發 | 台灣Pay |
31 | JKOON | 啟用 | 街口支付線上付款(消費者主掃) |
32 | JKOOF | 停用 | 街口支付線下付款(消費者被掃) |
附錄二:交易狀態代碼
以下回傳的狀態代碼均須處理,避免系統連線錯誤,MYPAY LINK回傳時,貴司系統無法判讀
狀態代碼 | 狀態說明 | 詳細說明 |
---|---|---|
100 | 資料錯誤 | MYPAYLINK收到資料,但是格式或資料錯誤 |
200 | 資料正確 | MYPAYLINK收到正確資料,會接續下一步交易 |
220 | 取消成功 | 如申請取消,取消訂單狀態為取消成功 |
230 | 退款成功 | 如申請退款,申請退款成功時狀態。 |
250 | 付款成功 | 此次交易,消費者付款成功 |
260 | 交易成功 尚未付款完成 |
超商代碼繳費-請等候消費者繳費入帳完成付款或消費者放棄交易,MYPAY LINK會再傳送一次結果: 250:代表消費者付款成功,此為最終結果 380:代表消費者沒有在時限內去繳費,逾期未去繳費,視同交易失敗,此為最終結果 |
265 | 訂單綁定 | 表示訂單編號生效,進入貸款頁面,但尚未註冊 最後會在回傳狀態 A0002:消費者放棄該筆交易,該筆交易視同交易失敗,為最終結果 275:無卡分期-請等候審查通過 |
270 | 交易成功 尚未付款完成 |
虛擬帳號-請等候消費者繳費入帳 完成付款或消費者放棄交易,MYPAY LINK會再傳送一次結果: 250:代表消費者付款成功,此為最終結果 380:代表消費者沒有在時限內去繳費,逾期未去繳費,視同交易失敗,此為最終結果 |
275 | 交易成功 待審核 (核貸中) |
無卡分期-請等候審查通過 核貸或婉拒,MYPAY LINK會再傳送一次結果: 250:代表該筆訂單已核貸,此為最終結果 380:代表該筆訂單沒有在時限內完成審核,視同交易失敗,此為最終結果 |
280 | 交易成功 尚未付款完成 |
儲值/WEBATM-線上待付款,等待狀態,等到使用者線上完成交易後MYPAY LINK會再傳送一次結果 250:代表消費者付款成功,此為最終結果 300:代表消費者付款失敗 |
290 | 交易成功 但資訊不符 |
交易成功,但資訊不符(包含金額不符、已逾期...等),該類型交易請特別注意 |
300 | 交易失敗 | 金流服務商回傳交易失敗或該筆交易超過風險控管限制規則 |
380 | 逾期交易 | 超商代碼或虛擬帳號交易,超過系統設定繳費期限 若經MYPAY LINK查詢驗證後,有機會在變更狀態 290:交易成功,但資訊不符 原因有可能是服務商的參數規則漏洞或是系統時間差異造成 |
400 | 系統錯誤訊息 | 若MYPAY LINK或上游服務商系統異常時 |
600 | 結帳完成 | 視為付款完成,此狀態為上游服務商確認訂單後的狀態,表示該筆訂單會撥款 透過MYPAY主動查詢或每日對帳機制 操作訂單功能內發動查詢功能 |
A0001 | 交易待確認 | MYPAY LINK與金流服務商發生連線異常,待查詢後確認結果,會主動再次回傳交易結果 250:代表消費者確實付款完成 600:結帳完成 300:金流服務商回傳交易失敗或超過風險控管限制規則交易 |
A0002 | 放棄交易 | 畫面導向MYPAY LINK後,消費者即放棄該筆交易,該筆交易視同交易失敗,為最終結果 |
B200 | 執行成功 | 處理成功執行 |
B500 | 執行失敗 | 處理時,資料異常不予以處理 |
附錄三:設定調整
- 交易回傳設定
- 交易金鑰重新發送與變更
附錄四:資料加密方式說明
1、所有的API送出HTTPs請求之欄位中,service 和 encry_data 欄位皆進行 AES256+BASE64 加密處理。 2、AES加密,格式為CBC,長度為256bits,金鑰長度32,IV長度16,傳遞內文為加密後組合IV並經過Base64轉換後傳出。
方式: 使用自訂的AES256函式將JSON資料加密後,再將IV資料和此AES256加密後的JSON資料串聯後,使用base64再進行加密成ASCII字串即可完成加密。
PHP加密示意: AesEncrypt -> base64_ecode($IV . $JSON)
C#加密示意: AesEncrypt -> (bytes)IV+(bytes)Json -> toBase64
附錄五:支援切換語系
支援語系名稱 | 語系編碼 |
---|---|
繁體中文版 | zh-TW(預設) |
簡體中文版 | zh-CN |
英文版 | en |
附錄六:測試區測試用信用卡卡號
下面卡號僅限在測試區測試使用
財金閘道
Visa | MasterCard | JCB | |
---|---|---|---|
卡號 | 4907060600015101 | 5409740002370101 | 3567430050009107 |
有效日期 | 1220 | 0419 | 0221 |
安全碼 | 615 | 106 | 315 |
3D交易密碼 | fisc1234 | Fisc1234 | Fisc1234 |
聯合信用卡中心閘道(其中MasterCard/JCB可測分期與紅利)
Visa | MasterCard | JCB | |
---|---|---|---|
卡號 | 4938170130000003 | 5430450100001219 | 3560500100001218 |
有效日期 | 1228 | 1218 | 1218 |
安全碼 | 985 | 214 | 023 |
3D交易密碼 | nccc1234 |
附錄七:支援交易幣別參數
幣別參數 | 說明 |
---|---|
TWD | 新台幣 |
CNY | 人民幣 |
附錄八:支援退款支付類型
支付類型 | 支付閘道 |
---|---|
信用卡 | 合庫、玉山、一銀、台灣支付、台北富邦、Acer |
海外信用卡 | 合庫、玉山、一銀、台灣支付、台北富邦、Acer |
銀聯卡 | 合庫、玉山 |
SmartPay | 合庫、一銀 |
附錄九:交易類型
代碼 | 名稱 | 說明 |
---|---|---|
1 | 網路交易(預設) | 由消費者輸入支付內容 |
2 | 實體交易 | 商戶面對消費者時,由商戶輸入支付內容做消費 |
附錄十:國內信用卡發卡單位
銀行名稱 | 銀行代碼 | 銀行名稱 | 銀行代碼 | 銀行名稱 | 銀行代碼 |
---|---|---|---|---|---|
土地銀行 | 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 |
附錄十一:Apple Pay憑證使用注意事項
1.使用我方憑證:
A.須提供我方一組Apple帳號加入sandbox。
B.我方的MID是merchant.inapp.mypay
2.使用自有憑證(代管):
A.依Mac電腦生成ECC-256憑證檔案,傳給我司 P12檔案即可。另需自行設定sandbox避免測試交易時產生實際付款行為。
附錄十二:eACH交易代碼
名稱 | 交易代碼 | 名稱 | 交易代碼 | 名稱 | 交易代碼 |
---|---|---|---|---|---|
慈善捐款 | 530 | 購物(非電子支付機構) | 560 | 網購退費 | 441 |
分期款 | 902 | 保全費 | 903 | 貨款 | 904 |
現金加值 | 908 | 租金(營利) | 909 | 會費(營利) | 910 |
仲介服務 | 912 | 貸款 | 405 | 消費貸款 | 803 |
附錄十三:『電子發票退款時使用作廢或折讓』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
4 | integer | 作廢或作廢重開 | 預設 |
6 | integer | 折讓 |
附錄十四:『商品項目』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
id | string | 商品編號 | 必填 |
name | string | 商品名稱 | 必填 |
cost | integer | 商品單價 | 必填 |
amount | integer | 商品數量 | 必填 |
total | integer | 商品小計 | 必填 |
image_url | string | 商品圖片連結(僅LINEPay線上使用) |
附錄十五:『退款完成回傳資訊』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
uid | string | 原MYPAYLINK 之交易流水號 | |
refund_uid | string | 退款之交易流水號(若多次退款,每次皆會不同) | |
key | string | 交易驗証碼 | |
prc | string | 主要交易回傳碼(retcode) | |
finishtime | string | 退款處理完成時間(YYYYMMDDHHmmss) | |
order_id | string | 貴特店系統的訂單編號 | |
user_id | string | 消費者帳號 | |
cost | string | 申請之退款金額 | |
currency | string | 申請之退款幣別 | |
actual_cost | string | 實際退款金額 | |
actual_currency | string | 實際退款幣別 | |
retmsg | string | 回傳訊息 | |
pfn | string | 付費方法 | |
payment_name | string | 定期定額式/定期分期式扣款名稱 | |
nois | string | 定期定額式/定期分期式扣繳期數 | |
group_id | string | 1.定期定額式扣款編號 2.定期分期式扣款編號 |
|
refund_type | string | 退款類型(1.直接線上退款 2.手動退款(信用卡類) 3.手動退款(現金類) | |
expected_refund_date | string | 現金退款預計退款日(YYYYMMDD) | |
echo_0 | string | 自訂回傳參數 1 | |
echo_1 | string | 自訂回傳參數 2 | |
echo_2 | string | 自訂回傳參數 3 | |
echo_3 | string | 自訂回傳參數 4 | |
echo_4 | string | 自訂回傳參數 5 |
附錄十六:『是否為經銷商代收費模式』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 是經銷商代收費模式 | |
0 | integer | 不是經銷商代收費模式 |
附錄十七: 『交易服務類型』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
0 | integer | 尚未進行閘道交易 | |
1 | integer | 代收代付 | |
2 | integer | 特店模式 |
附錄十八:『金流供應商代碼』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
A1 | string | 裕富數位資融 | |
A2 | string | 三環亞洲 | |
B0 | string | 新光銀行 | |
B1 | string | 永豐銀行 | |
B2 | string | 合作金庫 | |
B3 | string | 台北富邦 | |
B4 | string | 玉山銀行 | |
B5 | string | 台新銀行 | |
B6 | string | 聯合信用卡處理中心 | |
B7 | string | 台中商銀 | |
B8 | string | 中國信託商業銀行 | |
B9 | string | 上海商業儲蓄銀行 | |
BA | string | 第一銀行 | |
BB | string | 元大商業銀行 | |
BC | string | 凱基銀行 | |
BD | string | 國泰世華商業銀行 | |
BE | string | 華泰商業銀行 | |
BF | string | 兆豐銀行 | |
BG | string | 環滙亞太 | |
S0 | string | 全網行銷股份有限公司(FamiPort) | |
S1 | string | 安源資訊股份有限公司(ibon) | |
S2 | string | 萊爾富國際股份有限公司(Hi-Life) | |
T0 | string | 高鉅科技 | |
T1 | string | 藍新金流 | |
T2 | string | 統一客樂得(黑貓Pay) | |
W0 | string | 統振 | |
W1 | string | 遊戲橘子數位 | |
W2 | string | 台灣連線(LINEPay) | |
W3 | string | 博經 | |
W4 | string | 街口電子支付 | |
W5 | string | 悠遊卡 | |
W6 | string | 一卡通票證 | |
W7 | string | iCash | |
W8 | string | 全支付(PXPay plus) | |
W9 | string | 拍付國際資訊(Pi錢包) | |
E0 | string | MYTIX |
附錄十九: 『交易類型定義』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 一般 (預設) | |
2 | integer | 分期 | |
3 | integer | 紅利 |
附錄二十:『紅利資訊』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
type | string | 紅利類型 | 『紅利資訊類型』值參考 |
used | string | 紅利折抵點數 | |
amount | string | 自付金額 |
附錄二一:『分期資訊』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
period_number | integer | 分期期數 | |
total | integer | 應付總金額 | |
first | integer | 第一期應付金額 | |
every | integer | 第二期起每期應付金額 |
附錄二二: 『閘道內容回傳格式類型』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
0 | integer | 無法辨識 | |
1 | integer | 網址 | |
2 | integer | 超連結本文 | |
3 | integer | xml | |
4 | integer | json | |
5 | integer | csv | |
6 | integer | 串流 |
附錄二三:『資料內容所屬支付名稱』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
E_COLLECTION | string | 虛擬帳號 | |
IBON | string | iBON | |
FAMIPORT | string | FamiPort | |
LIFEET | string | LIFE-ET | |
WEBATM | string | WEBATM | |
CREDITCARD | string | 信用卡 | |
UNIONPAY | string | 銀聯卡 | |
SVC | string | 點數卡(GASH ,Imoney) | |
ABROAD | string | 海外信用卡 | |
ALIPAY | string | 支付寶 | |
string | 微信支付 | ||
LINEPAYON | string | LINE Pay線上付款 | |
LINEPAYOFF | string | LINE Pay線下付款 | |
WECHATOFF | string | 微信支付線下 | |
APPLEPAY | string | APPLE PAY | |
GOOGLEPAY | string | Google Pay | |
EACH | string | eACH交易 | |
CARDLESS | string | 無卡分期 | |
PION | string | Pi 拍錢包線上 | |
PIOFF | string | Pi 拍錢包線下 | |
AMEX | string | 美國運通 | |
JKOON | string | 街口支付線上 | |
JKOOFF | string | 街口支付線下 | |
ALIPAYOFF | string | 支付寶線下 | |
M_RECHARGE | string | 儲值交易 | |
EASYWALLETON | string | 悠遊付線上 | |
EASYWALLETOFF | string | 悠遊付線下 | |
AFP | string | 後付款 | |
BARCODE | string | 超商條碼繳費 |
附錄二四:『虛擬帳號回傳欄位』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
PinCode | string | 虛擬帳號 | |
LimitDate | string | 繳費有效期限,格式YYYYMMDDHHmmss | |
BankCode | string | 銀行代碼 |
附錄二五:『ibon』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
PinCode | string | 超商代碼(可用qrcode被掃) | |
LimitDate | string | 超商代碼繳費有效期限,格式YYYYMMDDHHmmss | |
BarCode1 | string | 三段條碼繳費條碼1(格式:Code-39 barcode) | |
BarCode2 | string | 三段條碼繳費條碼2(格式:Code-39 barcode) | |
BarCode3 | string | 三段條碼繳費條碼3(格式:Code-39 barcode) | |
BarcodeEndDate | string | 三段條碼繳費期限,格式YYYYMMDDHHmmss |
附錄二六:『FamiPort』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
PinCode | string | 繳費代碼(可憑此代碼至設備列印繳費單) | |
LimitDate | string | 繳費有效期限,格式YYYYMMDDHHmmss | |
BarCode1 | string | 三段條碼繳費條碼1(格式:Code-39 barcode) | |
BarCode2 | string | 三段條碼繳費條碼2(格式:Code-39 barcode) | |
BarCode3 | string | 三段條碼繳費條碼3(格式:Code-39 barcode) | |
BarcodeEndDate | string | 三段條碼繳費期限,格式YYYYMMDDHHmmss |
附錄二七: 『Life-ET』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
PinCode | string | 繳費代碼(可憑此代碼至設備列印繳費單) | |
BarCode1 | string | 繳費條碼1(格式:Code-39 barcode) | |
BarCode2 | string | 繳費條碼2(格式:Code-39 barcode) | |
BarCode3 | string | 繳費條碼3(格式:Code-39 barcode) | |
LimitDate | string | 繳費有效期限,格式YYYYMMDDHHmmss |
附錄二八:『交易查詢-退款資訊』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
uid | string | Payment Hub之交易流水號 | |
prc | string | 主要交易回傳碼(retcode) | |
cost | string | 總交易金額 | |
currency | string | 原交易幣別 | |
actual_cost | string | 實際交易金額 | |
actual_currency | string | 實際交易幣別 | |
retmsg | string | 回傳訊息 | |
finishtime | string | 交易完成時間(YYYYMMDDHHmmss) | |
appropriation_date | string | 預計撥款日期(YYYYMMDD) | |
invoice_state | integer | 發票開立狀態 | 『電子發票開立狀態類型』值參考 |
invoice_date | string | 發票開立日期(YYYYMMDD) | |
invoice_wordtrack | string | 發票字軌 | |
invoice_number | string | 發票號碼 | |
invoice_rand_code | string | 電子發票隨機碼 | |
invoice_seller_ban | string | 賣方統一編號 | |
invoice_buyer_ban | string | 買方統一編號 | |
invoice_left_qrcode | string | 電子發票左邊QrCode內容 | |
invoice_middle_barcode | string | 電子發票中間Barcode內容(格式Code-39) | |
invoice_right_qrcode | string | 電子發票右邊QrCode內容 | |
invoice_title_type | integer | 電子發票列印標題格式 | 『電子發票紙本列印標題類型』值參考 |
invoice_title | string | 電子發票列印標題內容 | |
invoice_amount | string | 電子發票銷售總額 | |
invoice_sales_amount | string | 電子發票銷售額 | |
invoice_tax_amount | string | 電子發票稅額 | |
invoice_order_detail | string | 電子發票全部產品明細(JSON格式) | 『商品細項』值參考 |
invoice_ratetype | integer | 電子發票稅率別 | 『電子發票稅率別』值參考 |
invoice_input_type | integer | 電子發票開立類型 | 『電子發票開立類型』值參考 |
invoice_allowance | array | 電子發票折讓資訊 | 每筆『電子發票折讓資訊』欄位參考 |
附錄二九: 『交易查詢-取消資訊』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
uid | string | Payment Hub之交易流水號 | |
prc | string | 主要交易回傳碼(retcode) | |
cost | string | 總交易金額 | |
currency | string | 原交易幣別 | |
actual_cost | string | 實際交易金額 | |
actual_currency | string | 實際交易幣別 | |
retmsg | string | 回傳訊息 | |
finishtime | string | 交易完成時間(YYYYMMDDHHmmss) |
附錄三十:『電子發票開立狀態類型』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
0 | integer | 不處理(預設) | |
1 | integer | 等候處理中, | |
2 | integer | 發票開立成功 | |
3 | integer | 發票處理失敗 | |
4 | integer | 作癈 | |
5 | integer | 系統或特約商店發票號碼設定不正確 | |
6 | integer | 折讓 |
附錄三一:『電子發票紙本列印標題類型』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 文字 | |
2 | integer | 圖形(圖片網址) |
附錄三二:『電子發票列印類型』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
0 | integer | 不列印 自行處置 | |
1 | integer | 列印 電子發票 + 商品明細 | |
2 | integer | 只印電子發票 | |
3 | integer | 只印商品明細 |
附錄三三:『電子發票列印設備』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
0 | integer | 自行處理 | |
1 | integer | SUNMI V2 PRO |
附錄三四:『商品細項』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
Description | string | 商品名稱 | |
Quantity | string | 數量 | |
UnitPrice | string | 單價 | |
Amount | string | 總金額 |
附錄三五:『電子發票稅率別』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 應稅(預設) | |
2 | integer | 零稅率 | |
3 | integer | 免稅 |
附錄三六:『電子發票開立類型』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 雲端發票 | |
2 | integer | 發票捐贈 | |
3 | integer | 實體發票 |
附錄三七:『電子發票折讓資訊』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
uid | string | 發生之退款交易流水號(UID) | |
amount | integer | 電子發票折讓金額 | |
order_detail | string | 電子發票折讓明細(JSON格式) | 『商品細項』值參考 |
附錄三八:『商品項目』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
id | string | 商品編號 | |
name | string | 商品名稱 | |
cost | string | 商品單價 | |
amount | string | 商品數量 | |
total | string | 商品小計 |
附錄三九:『紅利資訊類型』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 全額 | |
2 | integer | 部分 |
附錄四十:『雲端發票類型』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
2 | integer | 手機條碼 | |
3 | integer | 自然人憑證條碼 | |
4 | integer | 以E-Mail寄送 |