title: 經銷商 MYPAY LINK PayPage交易
language_tabs: # must be one of https://git.io/vQNgJ
- php
- csharp
- java
- javascript
- python
toc_footers:
includes:
- appendix1
- appendix2
- appendix3
- appendix4
- appendix5
- appendix6
- appendix7
search: true
經銷商 MYPAY LINK PayPage交易
修改歷程
| 版本 | 異動日期 | 修訂內容 | 位置 |
|---|---|---|---|
| 1.0 | 2021.01.01 | 新版文件 | |
| 1.0.1 | 2023.02.08 | 調整信用卡授權請款說明 | 20230208_01 |
| 1.0.2 | 2023.04.07 | 新增開發前請先閱讀 | 20230407_01 |
| 1.0.3 | 2023.05.31 | 新增定期扣款開發前請先閱讀 | 20230531_01 |
| 1.0.4 | 2023.07.26 | 新增特約商店可用支付工具 | 20230726_01 |
| 1.0.5 | 2023.10.11 | 金流交易回報,新增代收費模式回報 | 20231011_01 |
| 1.0.6 | 2023.11.22 | 金流交易回傳,狀態碼改變,超過5秒,http code =429 | |
| 1.0.7 | 2025.05.06 | 針對代收核銷請款加註說明 | 20240506_01 |
| 1.0.8 | 2025.09.26 | 核銷請款說明文字錯誤修正 | 20250926_01 |
開發前請先閱讀
金鑰的注意事項
Q:金鑰的有效期限
A:MyPay的金鑰有效期限只有一年,如果要延長,請自行至金鑰管理系統延長
Q:金鑰可以在什麼時候延長
A:到期日7天前,都可以延長(不包含第7天),一但超過,系統自動產生新金鑰後,即不可再延長
Q:金鑰即將到期前7天時,系統新發的金鑰是否會於信件中夾帶
A:會
Q:金鑰在到期前何時會發信通知
A:定期發送金鑰到期通知的頻率為:60天/30天/20天,若 貴司皆無動作,則系統會於到期前七天產製新金鑰並發送email到 貴司技術窗口信箱,此時舊的金鑰,因還未過期還可以使用,一旦過期,貴司仍使用舊金鑰則會無法交易
交易結果的告知
Q:交易完成的導頁會有交易結果的參數嗎
A:不論是參數中的success_returl 或 failure_returl或是後臺設定的交易成功、失敗導頁網址,均不會給予交易結果參數
Q:何時會給予交易結果
A:MyPay將在接收上游結果後,會由附錄三這邊的設定,背景主動發動通知商家
Q:當我接到MyPay通知時該做什麼
A:請直接回應8888,如沒有回應,MyPay會通知5次,若5次內均得不到8888,系統會寄發信件給予商家的技術人員以及附錄三而外設定的人員
定期扣款常見問題
Q:電子錢包綁定後可否執行一次性交易+定期定額扣款
A:只能執行一次性交易,無法使用定期扣款
Q:.API發動定期定額扣款,扣款失敗的話,會重扣幾次,多久重扣一次
A:不論是API建檔,還是後臺建檔,預設都是3天後發動重扣,並且只會執行一次,如果要調整,需要至後台調整((參考下圖,如太小請按右鍵可另開分頁放大)),API並無支援調整
Q:.定期定額扣款到一半時,消費者若想換信用卡扣款可以嗎?可透過 API 實現?
A:可以更換卡號,請從後台更改(參考下圖,如太小請按右鍵可另開分頁放大),無法透過API修改,或著發動取消扣款API,從新建立新的
串接錯誤
Q:為什麼我出現403錯誤
A:我司使用AWS WAF 防火牆,有針對user-agent做限制,請檢查user-agent是否帶入正常的資料,何謂正常的user-agent,可以參考Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
PayPage交易設計概要
安全性設計
所有的付費要求發動都僅能從特約商店的網頁伺服器發出請求,將傳輸的資料以AES加密,再透過HTTPS加密傳輸。交易資料不由消費者端送出,可確保資料不被消費者竄改。所有付費資訊經過MYPAY Link匝道進行轉送處理,特約商店不需要處理消費者的付費流程以及安全控管。
資料驗證
交易參數中有一組由雜湊函式運算出的驗証碼,作為資料驗証用,以確保資料正確性。 大部分交易模式,特約商店以導頁的方式處理付費流程,特約商店只需確保與MYPAY LINK連線正常,即可確保交易安全以及確保資料安全。
系統架構
所有請求與查詢只能透過伺服器發動,由特約商店的網頁伺服器利用伺服端服務程式發動交易,以避免交易資料被消費者竄改或攔截。為確保交易安全,MYPAY Link僅能接受 https connection,注意僅接受TLS1.2以上協定。
MYPAY LINK 目前提供之服務與格式
MYPAY LINK 提供多種交易與應用方式,應用情境如下:
(1)PayPage金流交易請求:透過MYPAY交易頁面作付款動作
(9)交易查詢:查詢金流交易資訊
(10)交易退款:金流交易退款,支援即時退款且未超過退款期限內之支付方式皆可使用此方式發動退款。
(11)信用卡取消授權:信用卡類交易,若使用自行請款模式,交易狀態為授權完成(245)時,則可以發動此信用卡取消授權,用以取消交易,並釋出消費者圈存金額。
(12)信用卡授權請款:信用卡類交易,若使用自行請款模式,交易狀態為授權完成(245)時,則可以發動此信用卡授權請款,用以完成交易。發動只限定一次。可全額或部分請款。
(13)取消定期定額式扣款:取消原有定期扣款訂單,亦可以從管理介面取消。
(14)MYPAY電子錢包綁定:以此API進行消費者信用卡綁定。
(15)取消退款:當該筆退款尚未送到金流服務商時,以取消之前發的退款訂單,若訂單已上傳到金流服務商則無效。
(16)電子發票開立:開立發票可在交易時一併發動請求 或交易成功後獨立發動開立發票。
(17)電子發票查詢:查詢電子發票開立狀態。
(18)代收款核銷撥款請求:經銷商發動代收款交易時,需要撥款給店家時,需發動核銷,才會出帳。
我們提供介接方式是透過https連線,只接受POST方式傳送交易資料。
介接網址
經銷商代特約商店發動模式
| 位置 | API介接網址 |
|---|---|
| 測試區 | https://ka.usecase.cc/api/agent |
| 正式區 | https://ka.mypay.tw/api/agent |
Client模式(限定功能)
| 位置 | API介接網址 |
|---|---|
| 測試區 | https://ka.usecase.cc/api/open |
| 正式區 | https://ka.mypay.tw/api/open |
資料加密方式
AES 256編碼 + base64編碼(附錄四資料加密方式)
加密金鑰
金鑰會透過mail發送,也可從管理後台取得
文字編碼
一律使用UTF-8相容編碼
PayPage金流交易
<?php
/**
* 經銷商串接-PayPage金流交易
*/
final class AgentOrder
{
/**
* 經銷商商務代號
* @var string
*/
public $agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
* @var string
*/
public $agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號(代特約商店發動)
* @var string
*/
public $storeUid = "289151880002";
/**
* 串接交易位置
* @var string
*/
public $url = "https://ka.usecase.cc/api/agent";
/**
* 取得串接欄位資料
* @return array
*/
public function getRawData()
{
$rawData = array();
$rawData['store_uid'] = $this->storeUid;
$rawData['items'] = [
[
'id' => '1',
'name' => '商品名稱',
'cost' => '1000',
'amount' => '1',
'total' => '1000'
]
];
$rawData['cost'] = 1000;
$rawData['user_id'] = "userid";
$rawData['order_id'] = "1234567890";
$rawData['ip'] = "192.168.0.1";
$rawData['pfn'] = "0";
$rawData['shipping_info'] = [
'shipment_type' => 2,
'name' => '金城武',
'tel' => '0900000123',
'zip_code' => '432',
'ship_address' => '台中市大肚區磺溪里15號'
];
return $rawData;
}
/**
* 取得服務位置
* @return array
*/
public function getService()
{
return array(
'service_name' => 'api',
'cmd' => 'api/orders'
);
}
/**
* AES 256 加密
* @param array $fields
* @param string $key
* @return string
*/
public 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;
}
/**
* 資料 POST 到主機
* @param array $postData
* @return mixed
*/
public function post($postData = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* 取得送出欄位資料
* @return array
*/
public function getPostData ()
{
$postData = array();
$postData['agent_uid'] = $this->agentUid;
$postData['service'] = $this->encrypt($this->getService(), $this->agentKey);
$postData['encry_data'] = $this->encrypt($this->getRawData(), $this->agentKey);
return $postData;
}
/**
* 執行
*/
public function run()
{
$json = $this->post($this->getPostData());
echo $json;
}
}
$AgentOrder = new AgentOrder();
$AgentOrder->run();
?>
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Dynamic;
/// <summary>
/// 建議使用.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也可能無法使用
/// </summary>
namespace MyPay {
/// <summary>
/// 經銷商串接-PayPage金流交易
/// </summary>
public class AgentOrder {
/// <summary>
/// 經銷商商務代號
/// </summary>
public string agentUid = "518169081001";
/// <summary>
/// 經銷商金鑰或認證碼
/// </summary>
public string agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/// <summary>
/// 特約商店商務代號
/// </summary>
public string storeUid = "289151880002";
/// <summary>
/// 串接交易位置
/// </summary>
public string url = "https://ka.usecase.cc/api/agent";
/// <summary>
/// 執行
/// </summary>
static void Main() {
AgentOrder simulator = new AgentOrder();
//僅限走https的Tls 1.2以上版本
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//發送至遠端
var result = simulator.Post(simulator.GetPostData());
System.Console.WriteLine(result);
}
/// <summary>
/// 取得串接欄位資料
/// </summary>
private dynamic GetRawData() {
ArrayList items = new ArrayList();
dynamic item = new ExpandoObject();
item.id = "1";
item.name = "商品名稱";
item.cost = "1000";
item.amount = "1";
item.total = "1000";
items.Add(item);
dynamic shippingInfo = new ExpandoObject();
shippingInfo.shipment_type = shipment_type;
shippingInfo.name = "金城武";
shippingInfo.tel = "0900000123";
shippingInfo.zip_code = "432";
shippingInfo.ship_address = "台中市大肚區磺溪里15號";
dynamic rawData = new ExpandoObject();
rawData.store_uid = this.storeUid;
rawData.items = items;
rawData.cost = 1000;
rawData.user_id = "userid";
rawData.order_id = "1234567890";
rawData.ip = "192.168.0.1";
rawData.pfn = "0";
rawData.shippingInfo = shippingInfo;
return rawData;
}
/// <summary>
/// 取得服務位置
/// </summary>
private ServiceRequest GetService() {
ServiceRequest rawData = new ServiceRequest();
rawData.service_name = "api";
rawData.cmd = "api/orders";
return rawData;
}
/// <summary>
/// 取得送出欄位資料
/// </summary>
private NameValueCollection GetPostData() {
string data_json = JsonConvert.SerializeObject(GetRawData(), Formatting.None);
string svr_json = JsonConvert.SerializeObject(GetService(), Formatting.None);; //依API種類調整
//產生AES向量
var IV = GetBytesIV();
//進行加密
var data_encode = Encrypt(data_json, this.agentKey, IV);
var svr_encode = Encrypt(svr_json, this.agentKey, IV);
//請注意使用的 Http Post 套件是否會自動加上UrlEncode,本Post範例為原始方式,故須加上UrlEncode
//若自行使用的套件會自動補上UrlEncode,則請忽略下面的UrlEncode,避免做了兩次UrlEncode
string data_toUrlEncode = HttpUtility.UrlEncode(data_encode);
string svr_toUrlEncode = HttpUtility.UrlEncode(svr_encode);
NameValueCollection postData = new NameValueCollection();
postData["agent_uid"] = this.agentUid;
postData["service"] = svr_toUrlEncode;
postData["encry_data"] = data_toUrlEncode;
return postData;
}
/// <summary>
/// AES 256 加密
/// </summary>
/// <param name="data"></param>
/// <param name="key"></param>
/// <param name="byteIV"></param>
/// <returns></returns>
private string Encrypt(string data, string key, byte[] byteIV) {
var byteKey = System.Text.Encoding.UTF8.GetBytes(key);
var enBytes = AES_Encrypt(data, byteKey, byteIV);
return Convert.ToBase64String(BytesAdd(byteIV, enBytes));
}
/// <summary>
/// AES 256 加密處理
/// </summary>
/// <param name="original"></param>
/// <param name="key"></param>
/// <param name="iv"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 轉換Bytes
/// </summary>
/// <param name="a"></param>
/// <param name="arryB"></param>
/// <returns></returns>
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();
}
/// <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;
}
/// <summary>
/// 資料 POST 到主機
/// </summary>
/// <param name="pars"></param>
/// <returns></returns>
private string Post(NameValueCollection pars) {
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(this.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>
/// 串接服務請求欄位
/// </summary>
public class ServiceRequest {
public string service_name { get; set; }
public string cmd { get; set; }
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URLEncoder;
import java.util.*;
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 static java.nio.charset.StandardCharsets.UTF_8;
import org.spongycastle.crypto.engines.AESEngine;
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 java.security.SecureRandom;
/**
* 經銷商串接-PayPage金流交易
* 1. jackson-core 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
* 2. jackson-databind 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
* 3. jackson-annotations 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
* 4. Spongy Castle 下載 https://mvnrepository.com/artifact/com.madgag.spongycastle/core
*/
public class AgentOrder {
/**
* 經銷商商務代號
*/
String agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
*/
String agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號
*/
String storeUid = "289151880002";
/**
* 串接交易位置
*/
String url = "https://ka.usecase.cc/api/agent";
/**
* 執行
* @param args
*/
public static void main(String[] args) {
AgentOrder simulator = new AgentOrder();
String json = simulator.post(simulator.getPostData());
System.out.print(json);
}
@SuppressWarnings(value = { "unchecked", "deprecation" })
/**
* 取得串接欄位資料
* @return 串接原始資料
*/
public Map getRawData() {
ArrayList items = new ArrayList();
Map<Object, Object> item = new HashMap<Object, Object>();
item.put("id", "1");
item.put("name", "商品名稱");
item.put("cost", "10");
item.put("amount", "1");
item.put("total", "10");
items.add(item);
Map<Object, Object> shippingInfo = new HashMap<Object, Object>();
shippingInfo.put("shipment_type", 2);
shippingInfo.put("name", "金城武");
shippingInfo.put("tel", "0900000123");
shippingInfo.put("zip_code", "432");
shippingInfo.put("ship_address", "台中市大肚區磺溪里15號");
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("store_uid", this.storeUid);
rawData.put("items", items);
rawData.put("cost", 10);
rawData.put("user_id", "userid");
rawData.put("order_id", "O20221216125917");
rawData.put("ip", "192.168.0.1");
rawData.put("pfn", "0");
rawData.put("shipping_info", shippingInfo);
return rawData;
}
/**
* 取得服務位置
* @return 串接服務資料
*/
public Map getService() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("service_name", "api");
rawData.put("cmd", "api/orders");
return rawData;
}
/**
* AES 256 加密
* @param rawData 原始資料
* @param AesKey AES256金鑰字串
* @return 轉換成Base64資料
*/
public String encrypt(Map rawData, String AesKey) {
try {
ObjectMapper objMapper = new ObjectMapper();
byte[] data = objMapper.writeValueAsString(rawData).getBytes(UTF_8);
byte[] key = AesKey.getBytes(UTF_8);
// 16 bytes is the IV size for AES256
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
// 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);
Base64.Encoder encoder = Base64.getEncoder();
String base64 = encoder.encodeToString(outBuf2);
return base64;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
/**
* 資料 POST 到主機
* @param qstr 串接資料
* @return 服務回傳JSON資訊
*/
public String post(String qstr) {
String result = "";
try {
// 資料
byte[] qstr_bytes = qstr.getBytes(StandardCharsets.UTF_8);
URL iurl = new URL(this.url);
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 + "\r\n");
}
try {
result = response.toString();
} finally {
in.close();
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return result;
}
/**
* 取得送出欄位資料
* @return POST完整資料
*/
public String getPostData() {
String postData = "";
try {
// Base64需要使用UrlEncode做傳輸
String data_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getRawData(), this.agentKey), "UTF-8");
String svr_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getService(), this.agentKey), "UTF-8");
postData = "agent_uid=" + this.agentUid + "&service="
+ svr_toUrlEncode + "&encry_data=" + data_toUrlEncode;
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return postData;
}
}
const crypto = require('crypto');
const httpRequest = require('https');
/**
* 經銷商串接-PayPage金流交易
*/
function AgentOrder() {
// 經銷商商務代號
this.agentUid = "518169081001";
// 經銷商金鑰或認證碼
this.agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
// 特約商店商務代號
this.storeUid = "289151880002";
// 串接交易位置
this.url = "https://ka.usecase.cc/api/agent";
};
/**
* 取得串接欄位資料
*/
AgentOrder.prototype.getRawData = function () {
return {
store_uid: this.storeUid,
items: [
{
'id': "1",
'name': "商品名稱",
'cost': "1000",
'amount': "1",
'total': "1000"
}
],
cost: 1000,
user_id: "userid",
order_id: "1234567890",
ip: "192.168.0.1",
pfn: "0",
shipping_info: {
'shipment_type': 2,
'name': "金城武",
'tel': "0900000123",
'zip_code': "432",
'ship_address': "台中市大肚區磺溪里15號"
},
};
};
/**
* 取得服務位置
*/
AgentOrder.prototype.getService = function () {
return {
service_name: "api",
cmd: "api/orders"
};
};
/**
* AES 256 加密
*/
AgentOrder.prototype.encrypt = function (fields, key) {
let eData = JSON.stringify(fields);
const blockSize = 16;
const iv = crypto.randomBytes(blockSize);
const encryptor = crypto.createCipheriv('aes-256-cbc', key, iv);
let tmpCipher = encryptor.update(Buffer.from(eData));
let finalCipher = encryptor.final();
const tempData = Buffer.concat([tmpCipher, finalCipher], tmpCipher.length + finalCipher.length);
let data = Buffer.concat([iv, tempData], iv.length + tempData.length).toString('base64');
return data;
};
/**
* 資料 POST 到主機
*/
AgentOrder.prototype.post = function (postData) {
return new Promise((res, rej) => {
let options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
rejectUnauthorized: false
};
let send_process = httpRequest.request(this.url, options, (api_res) => {
let res_data = "";
api_res.on('data', (tmp_data) => {
res_data += tmp_data;
});
api_res.on('end', () => {
res(res_data);
});
});
send_process.write(JSON.stringify(postData));
send_process.end();
});
};
/**
* 取得送出欄位資料
*/
AgentOrder.prototype.getPostData = function () {
return {
"agent_uid": this.agentUid,
"service": this.encrypt(this.getService(), this.agentKey),
"encry_data": this.encrypt(this.getRawData(), this.agentKey)
};
};
/**
* 執行
*/
AgentOrder.prototype.run = async function () {
json = await this.post(this.getPostData())
console.log(json);
};
AgentOrder = new AgentOrder();
AgentOrder.run();
# -*- coding: utf-8 -*-
import json
import base64
import requests
from Crypto.Cipher import AES
from Crypto.Util import Padding
from Crypto.Random import get_random_bytes
"""經銷商串接-PayPage金流交易
"""
class AgentOrder:
# 經銷商商務代號
agentUid = "518169081001";
# 經銷商金鑰或認證碼
agentKey = b"0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
# 特約商店商務代號
storeUid = "289151880002"
# 串接交易位置
url = "https://ka.usecase.cc/api/agent"
def getRawData(self):
"""取得串接欄位資料
Returns:
{dict}: 欄位資料
"""
rawData = {
'store_uid': self.storeUid,
'items': [
{
'id': "1",
'name': "商品名稱",
'cost': "1000",
'amount': "1",
'total': "1000"
}
],
'cost': 1000,
'user_id': "userid",
'order_id': "1234567890",
'ip': "192.168.0.1",
'pfn': "0",
'shipping_info': {
'shipment_type': 2,
'name': "金城武",
'tel': "0900000123",
'zip_code': "432",
'ship_address': "台中市大肚區磺溪里15號"
},
}
return rawData
def getService(self):
"""取得服務位置
Returns:
{dict}: 服務位置資料
"""
return {
'service_name': 'api',
'cmd': 'api/orders'
}
def encrypt(self, fields, key):
"""AES 256 加密
Args:
fields {dict}: 欄位資料
key {bytes}: AES金鑰
Returns:
{string}: 加密資料
"""
data = json.dumps(fields, separators=(',', ':'))
data = Padding.pad(data.encode('utf-8'), AES.block_size)
iv = get_random_bytes(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
data = cipher.encrypt(data)
data = base64.b64encode(iv + data)
return data
def post(self, postData):
"""資料 POST 到主機
Args:
postData {dict}: 欄位資料
Returns:
{string}: JSON資料
"""
result = requests.post(self.url, postData)
return result.text
def getPostData(self):
"""取得送出欄位資料
Returns:
{dict}: 欄位資料
"""
postData = {
'agent_uid': self.agentUid,
'service': self.encrypt(self.getService(), self.agentKey),
'encry_data': self.encrypt(self.getRawData(), self.agentKey)
}
return postData
def run(self):
"""執行
"""
json = self.post(self.getPostData())
print(json)
AgentOrder = AgentOrder()
AgentOrder.run()
回傳 JSON 結構如下:
{
"code": "200",
"msg": "資料正確",
"url": "http:\/\/pay.k20-mypay.tw\/payment\/81127.html",
"uid": 81127,
"key": "af4e678325dd49f8036949c38ab04105"
}此交易請求參數內含交易訂單編號,與查詢用之金鑰,以及付費網址。貴司也可將此交易訂單編號綁定貴司的消費者訂單,我們會透過主動回報機制,以POST方式回報交易即時資訊,回報網址可以在管理系統中設定,啟動服務後,系統就會主動回傳訂單狀態。
經銷商『PayPage金流交易』參數說明
| 欄位 | 型態 | 說明 |
|---|---|---|
| agent_uid | string(16) | 經銷商商務代號 |
| service | text | {"service_name": "api", "cmd": "api\/orders"}JSON格式,AES256加密資料 |
| encry_data | text | 『PayPage金流交易』欄位參考 JSON格式,AES256加密資料 |
『PayPage金流交易』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| store_uid | string | 特約商店代碼 | 必填 |
| user_id | string | 消費者帳號 請注意,記憶卡號跟記憶發票都是依此欄位為基準,如果不同的user來買,請記得切換,否則會出現同一筆資料 | 必填 |
| user_name | string | 消費者姓名,電子錢包交易必要欄位 | |
| user_real_name | string | 消費者真實姓名,電子錢包交易必要欄位 | |
| user_zipcode | string | 消費者郵遞區號 | |
| user_address | string | 消費者帳單地址 | |
| user_sn_type | string | 證號類型 | 『證號類型』值參考 |
| user_sn | string | 付款人身分證/統一證號/護照號碼 | |
| user_phone | string | 消費者家用電話 | |
| user_cellphone_code | string | 消費者行動電話國碼,電子錢包交易必要欄位 | |
| user_cellphone | string | 消費者行動電話,電子錢包交易必要欄位 | |
| user_email | string | 消費者 E-Mail,電子錢包交易必要欄位 | |
| user_birthday | string | 消費者生日 | |
| cost | string | 訂單總金額 = 物品之總價加總 + 折價 + 運費(如為定期定額交易,此為每一期的應扣金額) | 必填 |
| currency | string | 預設交易幣別(預設為TWD新台幣) | 『幣別類型』值參考 |
| enable_dcc | integer | 啟用dcc(自動換匯) | 『自動換匯』值參考 |
| order_id | string | 訂單編號(訂單編號最長為50bytes) | 必填 |
| ip | string | 消費者來源 IP (格式務必正確,部分金流服務商後續處理會驗證) | 必填 |
| item | string | 訂單內物品數 | |
| items | array | 訂單物品項目 | 必填 每筆『商品項目』欄位參考 |
| regular | string | 定期定額付費,期數單位 | 『分期類型定義』值參考 |
| regular_total | string | 總期數(如為 12 期即代入 12,如果不設定終止期,請代入 0) | |
| regular_first_charge_date | string | 定期扣款起扣日 不得小於當日,若未指定日期,將判定為當日扣款 格式為 YYYYMMDD,如 20090916 | |
| group_id | string | 定期定額式扣款編號 | |
| echo_0 | string | 自訂回傳參數 1 | |
| echo_1 | string | 自訂回傳參數 2 | |
| echo_2 | string | 自訂回傳參數 3 | |
| echo_3 | string | 自訂回傳參數 4 | |
| echo_4 | string | 自訂回傳參數 5 | |
| pfn | string | 預選付費方法,可用,分開,例如CREDITCARD,LINEPAYON,APPLEPAY | 『付款方式』值參考 |
| interface | string | 消費者操作介面類型 pc/app | |
| discount | string | 折價金額 (預設0),如果有使用發票功能,建議將折扣資訊放入item。 | |
| success_returl | string | 交易成功導頁網址 | |
| failure_returl | string | 交易失敗導頁網址 | |
| homepage_url | string | paypage頁面上,返回商家頁面的按鈕url | |
| limit_pay_days | integer | 虛擬帳號與超商代碼使用之有效天數 | |
| shipping_fee | string | 運費 | |
| enable_quickpay | integer | 啟用快速結帳 | 『啟用快速結帳』值參考 |
| enable_ewallet | integer | 啟用電子錢包 | 『啟用電子錢包』值參考 |
| virtual_pan | string | 電子錢包虛擬卡號 | |
| ewallet_type | integer | 電子錢包執行類型 | 『電子錢包執行類型』值參考 |
| transaction_type | integer | 交易類型 | 『交易類型』值參考 |
| creditcard_installment | string | 國內信用卡分期顯示限定 JSON 格式如下 { "3": ["013", "822", "808"], "6": ["822", "812"] } | |
| cardless_code | string | 無卡分期商品代碼 | |
| cardless_installment | string | 無卡分期顯示消費者可選擇之期數,格式為陣列,例: [3, 6, 9, 12] | |
| each_code | string | eACH交易代碼(如果使用eACH必須指定交易代碼) | |
| issue_invoice_state | integer | 開立發票 | 『電子發票是否開立狀態』值參考 |
| invoice_ratetype | integer | 電子發票稅率別 | 『電子發票稅率別』值參考 |
| invoice_input_type | integer | 電子發票開立類型 | 『電子發票開立類型』值參考 |
| invoice_cloud_type | string | 「雲端發票」類型 | 當invoice_input_type為1,此狀態才有效 『雲端發票類型』值參考 |
| invoice_tax_id | string | 統一編號 | 當invoice_input_type為1,此欄位才有效,非必要 |
| invoice_mobile_code | string | 手機條碼 | 當invoice_cloud_type為2,此欄位才有效 |
| invoice_natural_person | string | 自然人憑證條碼 | 當invoice_cloud_type為3,此欄位才有效 |
| invoice_love_code | string | 愛心碼 | 當invoice_input_type為2,此欄位才有效 |
| invoice_b2b_title | string | 發票抬頭 | 當invoice_input_type為3時,此欄位才有效 |
| invoice_b2b_id | string | 統一編號 | 當invoice_input_type為3時,此欄位才有效 |
| invoice_b2b_address | string | 發票地址 | 當invoice_input_type為3時,此欄位才有效 |
| invoice_b2b_title_force | string | 若選擇實體發票時,發票抬頭無法異動。 | 『電子發票欄位異動』值參考 |
| invoice_b2b_id_force | string | 若選擇實體發票時,統一編號無法異動。 | 『電子發票欄位異動』值參考 |
| invoice_b2b_address_force | integer | 若選擇實體發票時,預設地址無法異動。 | 『電子發票欄位異動』值參考 |
| user_data | object | 無卡分期消費者資訊 | 『無卡分期消費者資訊』欄位參考 |
| files_path | string | 無卡分期上傳檔案路徑 (JSON多筆格式) | 『無卡分期檔案』值參考 |
| price | string | 儲值交易之交易金額/點數 (儲值交易以此欄位辨識交易金額/點數) | |
| recharge_code | string | 儲值交易時,使用當時儲值之儲值產品代碼 | |
| recharge_items | array | 儲值交易用物品資訊 | 每筆『儲值交易項目』欄位參考 |
| agent_sms_fee_type | integer | 經銷商代收費是否含簡訊費 | 『含不含簡訊費』值參考 |
| agent_charge_fee_type | integer | 經銷商代收費是否含手續費 | 『含不含手續費類型』值參考 |
| agent_charge_fee | integer | 經銷商代收費 | |
| integer | 是否為經銷商代收費模式 若 is_agent_charge 有指定,以指定優先 若欄位agent_charge_fee有費用,或經銷商代收費是含簡訊費、或經銷商代收費含手續費,則預設為1 若欄位agent_charge_fee無費用,且經銷商代收費不含簡訊費、或經銷商代收費不含手續費或參欄位都未使用則預設為0 只限於高鉅代收的支付工具,非代收及行動支付類型的支付工具均不支援,會自動轉為一般訂單 | 『是否為經銷商代收費模式』值參考 | |
| shipping_info | object | 送貨資訊 (後付款為必填) | 『後付款送貨資訊』欄位參考 |
| creditcard_is_automatic_payment | string | 信用卡類交易時,是否使用授權請款模式(預設自動請款) | 『信用卡授權請款模式類型』值參考 |
『PayPage金流交易』回傳欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| code | string | 交易回傳碼 | |
| msg | string | 回傳訊息 | |
| uid | string | 訂單之交易流水號(交易訂單/票券服務訂單/儲值訂單) | |
| key | string | 交易驗証碼 | |
| url | string | 交易網址 |
| 支援語系名稱 | 語系編碼 |
|---|---|
| 繁體中文版 | zh-TW(預設) |
| 簡體中文版 | zh-CN |
| 英文版 | en |
| 印尼語 | id |
『交易完成回傳資訊』回報欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| uid | string | Payment Hub之交易流水號 | |
| key | string | 交易驗証碼 | |
| prc | string | 主要交易回傳碼(retcode) | |
| finishtime | string | 交易完成時間(YYYYMMDDHHmmss) | |
| cardno | string | 銀行端口回傳碼 | |
| acode | string | 授權碼 | |
| card_type | 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 | integer | 交易類型 | 『交易類型定義』值參考 |
| redeem | string | 紅利資訊 JSON 格式 | 『紅利資訊』值參考 |
| installment | string | 信用卡分期資訊 JSON 格式 | 『分期資訊』值參考 |
| payment_name | string | 定期定額式/定期分期式扣款名稱 | |
| nois | string | 定期定額式/定期分期式扣繳期數 | |
| group_id | string | 1.定期定額式扣款編號 2.定期分期式扣款編號 | |
| bank_id | string | 銀行代碼 虛擬帳號資訊 | |
| expired_date | string | 有效日期(YYYYMMDDHHmmss) 虛擬帳號、超商代碼、無卡分期資訊 | |
| result_type | integer | 虛擬帳號、超商代碼 資料格式類型 | 『閘道內容回傳格式類型』值參考 |
| result_content_type | string | 資料內容所屬支付名稱 | 『資料內容所屬支付名稱』值參考 |
| result_content | string | 虛擬帳號、超商代碼 資料內容 | 『虛擬帳號回傳欄位』值參考 『ibon』值參考 『FamiPort』值參考 『Life-ET』值參考 『超商條碼繳費』值參考 |
| echo_0 | string | 自訂回傳參數 1 | |
| echo_1 | string | 自訂回傳參數 2 | |
| echo_2 | string | 自訂回傳參數 3 | |
| echo_3 | string | 自訂回傳參數 4 | |
| echo_4 | string | 自訂回傳參數 5 |
『非即時交易回傳資訊』回報欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| uid | string | Payment Hub之交易流水號 | |
| key | string | 交易驗証碼 | |
| prc | string | 主要交易回傳碼(retcode) | |
| cardno | string | 銀行端口回傳碼 | |
| acode | string | 授權碼 | |
| card_type | string | 信用卡卡別 | 『信用卡別類型』值參考 |
| issuing_bank | string | 發卡行 | |
| issuing_bank_uid | string | 發卡銀行代碼 | |
| is_agent_charge | int | 是否為經銷商代收費模式 | 『是否為經銷商代收費模式』值參考 |
| transaction_mode | integer | 交易服務類型 | 『交易服務類型』值參考 |
| supplier_name | string | 交易之金融服務商 | |
| supplier_code | string | 交易之金融服務商代碼 | 『金流供應商代碼』值參考 |
| finishtime | string | 交易完成時間(YYYYMMDDHHmmss) | |
| 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 | integer | 交易類型 | 『交易類型定義』值參考 |
| redeem | string | 紅利資訊 JSON 格式 | 『紅利資訊』值參考 |
| installment | string | 信用卡分期資訊 JSON 格式 | 『分期資訊』值參考 |
| payment_name | string | 定期定額式/定期分期式扣款名稱 | |
| nois | string | 定期定額式/定期分期式扣繳期數 | |
| group_id | string | 1.定期定額式扣款編號 2.定期分期式扣款編號 | |
| bank_id | string | 銀行代碼 虛擬帳號資訊 | |
| expired_date | string | 有效日期(YYYYMMDDHHmmss) 虛擬帳號、超商代碼、無卡分期資訊 | |
| result_type | integer | 虛擬帳號、超商代碼 資料格式類型 | 『閘道內容回傳格式類型』值參考 |
| result_content_type | string | 資料內容所屬支付名稱 | 『資料內容所屬支付名稱』值參考 |
| result_content | string | 虛擬帳號、超商代碼 資料內容 | 『虛擬帳號回傳欄位』值參考 『ibon』值參考 『FamiPort』值參考 『Life-ET』值參考 |
| echo_0 | string | 自訂回傳參數 1 | |
| echo_1 | string | 自訂回傳參數 2 | |
| echo_2 | string | 自訂回傳參數 3 | |
| echo_3 | string | 自訂回傳參數 4 | |
| echo_4 | string | 自訂回傳參數 5 |
『訂單確認回傳資訊』回報欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| uid | string | Payment Hub之交易流水號 | |
| key | string | 交易驗証碼 | |
| prc | string | 主要交易回傳碼(retcode) | |
| finishtime | string | 交易完成時間(YYYYMMDDHHmmss) | |
| cardno | string | 銀行端口回傳碼 | |
| acode | string | 授權碼 | |
| card_type | 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 | integer | 交易類型 | 『交易類型定義』值參考 |
| redeem | string | 紅利資訊 JSON 格式 | 『紅利資訊』值參考 |
| installment | string | 信用卡分期資訊 JSON 格式 | 『分期資訊』值參考 |
| payment_name | string | 定期定額式/定期分期式扣款名稱 | |
| nois | string | 定期定額式/定期分期式扣繳期數 | |
| group_id | string | 1.定期定額式扣款編號 2.定期分期式扣款編號 | |
| bank_id | string | 銀行代碼 虛擬帳號資訊 | |
| expired_date | string | 有效日期(YYYYMMDDHHmmss) 虛擬帳號、超商代碼、無卡分期資訊 | |
| result_type | integer | 虛擬帳號、超商代碼 資料格式類型 | 『閘道內容回傳格式類型』值參考 |
| result_content_type | string | 資料內容所屬支付名稱 | 『資料內容所屬支付名稱』值參考 |
| result_content | string | 虛擬帳號、超商代碼 資料內容 | 『虛擬帳號回傳欄位』值參考 『ibon』值參考 『FamiPort』值參考 『Life-ET』值參考 |
| echo_0 | string | 自訂回傳參數 1 | |
| echo_1 | string | 自訂回傳參數 2 | |
| echo_2 | string | 自訂回傳參數 3 | |
| echo_3 | string | 自訂回傳參數 4 | |
| echo_4 | string | 自訂回傳參數 5 |
交易查詢
<?php
/**
* 經銷商串接-交易查詢
*/
final class AgentQuery
{
/**
* 經銷商商務代號
* @var string
*/
public $agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
* @var string
*/
public $agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號(代特約商店發動)
* @var string
*/
public $storeUid = "289151880002";
/**
* 串接交易位置
* @var string
*/
public $url = "https://ka.usecase.cc/api/agent";
/**
* 取得串接欄位資料
* @return array
*/
public function getRawData()
{
$rawData = array();
$rawData['uid'] = "95217";
$rawData['key'] = "3425042d7d266e4aea5fd4653a0271db";
return $rawData;
}
/**
* 取得服務位置
* @return array
*/
public function getService()
{
return array(
'service_name' => 'api',
'cmd' => 'api/queryorder'
);
}
/**
* AES 256 加密
* @param array $fields
* @param string $key
* @return string
*/
public 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;
}
/**
* 資料 POST 到主機
* @param array $postData
* @return mixed
*/
public function post($postData = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* 取得送出欄位資料
* @return array
*/
public function getPostData ()
{
$postData = array();
$postData['agent_uid'] = $this->agentUid;
$postData['service'] = $this->encrypt($this->getService(), $this->agentKey);
$postData['encry_data'] = $this->encrypt($this->getRawData(), $this->agentKey);
return $postData;
}
/**
* 執行
*/
public function run()
{
$json = $this->post($this->getPostData());
echo $json;
}
}
$AgentQuery = new AgentQuery();
$AgentQuery->run();
?>
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Dynamic;
/// <summary>
/// 建議使用.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也可能無法使用
/// </summary>
namespace MyPay {
/// <summary>
/// 經銷商串接-交易查詢
/// </summary>
public class AgentQuery {
/// <summary>
/// 經銷商商務代號
/// </summary>
public string agentUid = "518169081001";
/// <summary>
/// 經銷商金鑰或認證碼
/// </summary>
public string agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/// <summary>
/// 特約商店商務代號
/// </summary>
public string storeUid = "289151880002";
/// <summary>
/// 串接交易位置
/// </summary>
public string url = "https://ka.usecase.cc/api/agent";
/// <summary>
/// 執行
/// </summary>
static void Main() {
AgentQuery simulator = new AgentQuery();
//僅限走https的Tls 1.2以上版本
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//發送至遠端
var result = simulator.Post(simulator.GetPostData());
System.Console.WriteLine(result);
}
/// <summary>
/// 取得串接欄位資料
/// </summary>
private dynamic GetRawData() {
dynamic rawData = new ExpandoObject();
rawData.uid = "95217";
rawData.key = "3425042d7d266e4aea5fd4653a0271db";
return rawData;
}
/// <summary>
/// 取得服務位置
/// </summary>
private ServiceRequest GetService() {
ServiceRequest rawData = new ServiceRequest();
rawData.service_name = "api";
rawData.cmd = "api/queryorder";
return rawData;
}
/// <summary>
/// 取得送出欄位資料
/// </summary>
private NameValueCollection GetPostData() {
string data_json = JsonConvert.SerializeObject(GetRawData(), Formatting.None);
string svr_json = JsonConvert.SerializeObject(GetService(), Formatting.None);; //依API種類調整
//產生AES向量
var IV = GetBytesIV();
//進行加密
var data_encode = Encrypt(data_json, this.agentKey, IV);
var svr_encode = Encrypt(svr_json, this.agentKey, IV);
//請注意使用的 Http Post 套件是否會自動加上UrlEncode,本Post範例為原始方式,故須加上UrlEncode
//若自行使用的套件會自動補上UrlEncode,則請忽略下面的UrlEncode,避免做了兩次UrlEncode
string data_toUrlEncode = HttpUtility.UrlEncode(data_encode);
string svr_toUrlEncode = HttpUtility.UrlEncode(svr_encode);
NameValueCollection postData = new NameValueCollection();
postData["agent_uid"] = this.agentUid;
postData["service"] = svr_toUrlEncode;
postData["encry_data"] = data_toUrlEncode;
return postData;
}
/// <summary>
/// AES 256 加密
/// </summary>
/// <param name="data"></param>
/// <param name="key"></param>
/// <param name="byteIV"></param>
/// <returns></returns>
private string Encrypt(string data, string key, byte[] byteIV) {
var byteKey = System.Text.Encoding.UTF8.GetBytes(key);
var enBytes = AES_Encrypt(data, byteKey, byteIV);
return Convert.ToBase64String(BytesAdd(byteIV, enBytes));
}
/// <summary>
/// AES 256 加密處理
/// </summary>
/// <param name="original"></param>
/// <param name="key"></param>
/// <param name="iv"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 轉換Bytes
/// </summary>
/// <param name="a"></param>
/// <param name="arryB"></param>
/// <returns></returns>
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();
}
/// <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;
}
/// <summary>
/// 資料 POST 到主機
/// </summary>
/// <param name="pars"></param>
/// <returns></returns>
private string Post(NameValueCollection pars) {
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(this.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>
/// 串接服務請求欄位
/// </summary>
public class ServiceRequest {
public string service_name { get; set; }
public string cmd { get; set; }
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URLEncoder;
import java.util.*;
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 static java.nio.charset.StandardCharsets.UTF_8;
import org.spongycastle.crypto.engines.AESEngine;
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 java.security.SecureRandom;
/**
* 經銷商串接-交易查詢
* 1. jackson-core 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
* 2. jackson-databind 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
* 3. jackson-annotations 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
* 4. Spongy Castle 下載 https://mvnrepository.com/artifact/com.madgag.spongycastle/core
*/
public class AgentQuery {
/**
* 經銷商商務代號
*/
String agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
*/
String agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號
*/
String storeUid = "289151880002";
/**
* 串接交易位置
*/
String url = "https://ka.usecase.cc/api/agent";
/**
* 執行
* @param args
*/
public static void main(String[] args) {
AgentQuery simulator = new AgentQuery();
String json = simulator.post(simulator.getPostData());
System.out.print(json);
}
@SuppressWarnings(value = { "unchecked", "deprecation" })
/**
* 取得串接欄位資料
* @return 串接原始資料
*/
public Map getRawData() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("uid", "95217");
rawData.put("key", "3425042d7d266e4aea5fd4653a0271db");
return rawData;
}
/**
* 取得服務位置
* @return 串接服務資料
*/
public Map getService() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("service_name", "api");
rawData.put("cmd", "api/queryorder");
return rawData;
}
/**
* AES 256 加密
* @param rawData 原始資料
* @param AesKey AES256金鑰字串
* @return 轉換成Base64資料
*/
public String encrypt(Map rawData, String AesKey) {
try {
ObjectMapper objMapper = new ObjectMapper();
byte[] data = objMapper.writeValueAsString(rawData).getBytes(UTF_8);
byte[] key = AesKey.getBytes(UTF_8);
// 16 bytes is the IV size for AES256
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
// 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);
Base64.Encoder encoder = Base64.getEncoder();
String base64 = encoder.encodeToString(outBuf2);
return base64;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
/**
* 資料 POST 到主機
* @param qstr 串接資料
* @return 服務回傳JSON資訊
*/
public String post(String qstr) {
String result = "";
try {
// 資料
byte[] qstr_bytes = qstr.getBytes(StandardCharsets.UTF_8);
URL iurl = new URL(this.url);
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 + "\r\n");
}
try {
result = response.toString();
} finally {
in.close();
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return result;
}
/**
* 取得送出欄位資料
* @return POST完整資料
*/
public String getPostData() {
String postData = "";
try {
// Base64需要使用UrlEncode做傳輸
String data_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getRawData(), this.agentKey), "UTF-8");
String svr_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getService(), this.agentKey), "UTF-8");
postData = "agent_uid=" + this.agentUid + "&service="
+ svr_toUrlEncode + "&encry_data=" + data_toUrlEncode;
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return postData;
}
}
const crypto = require('crypto');
const httpRequest = require('https');
/**
* 經銷商串接-交易查詢
*/
function AgentQuery() {
// 經銷商商務代號
this.agentUid = "518169081001";
// 經銷商金鑰或認證碼
this.agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
// 特約商店商務代號
this.storeUid = "289151880002";
// 串接交易位置
this.url = "https://ka.usecase.cc/api/agent";
};
/**
* 取得串接欄位資料
*/
AgentQuery.prototype.getRawData = function () {
return {
uid: "95217",
key: "3425042d7d266e4aea5fd4653a0271db",
};
};
/**
* 取得服務位置
*/
AgentQuery.prototype.getService = function () {
return {
service_name: "api",
cmd: "api/queryorder"
};
};
/**
* AES 256 加密
*/
AgentQuery.prototype.encrypt = function (fields, key) {
let eData = JSON.stringify(fields);
const blockSize = 16;
const iv = crypto.randomBytes(blockSize);
const encryptor = crypto.createCipheriv('aes-256-cbc', key, iv);
let tmpCipher = encryptor.update(Buffer.from(eData));
let finalCipher = encryptor.final();
const tempData = Buffer.concat([tmpCipher, finalCipher], tmpCipher.length + finalCipher.length);
let data = Buffer.concat([iv, tempData], iv.length + tempData.length).toString('base64');
return data;
};
/**
* 資料 POST 到主機
*/
AgentQuery.prototype.post = function (postData) {
return new Promise((res, rej) => {
let options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
rejectUnauthorized: false
};
let send_process = httpRequest.request(this.url, options, (api_res) => {
let res_data = "";
api_res.on('data', (tmp_data) => {
res_data += tmp_data;
});
api_res.on('end', () => {
res(res_data);
});
});
send_process.write(JSON.stringify(postData));
send_process.end();
});
};
/**
* 取得送出欄位資料
*/
AgentQuery.prototype.getPostData = function () {
return {
"agent_uid": this.agentUid,
"service": this.encrypt(this.getService(), this.agentKey),
"encry_data": this.encrypt(this.getRawData(), this.agentKey)
};
};
/**
* 執行
*/
AgentQuery.prototype.run = async function () {
json = await this.post(this.getPostData())
console.log(json);
};
AgentQuery = new AgentQuery();
AgentQuery.run();
# -*- coding: utf-8 -*-
import json
import base64
import requests
from Crypto.Cipher import AES
from Crypto.Util import Padding
from Crypto.Random import get_random_bytes
"""經銷商串接-交易查詢
"""
class AgentQuery:
# 經銷商商務代號
agentUid = "518169081001";
# 經銷商金鑰或認證碼
agentKey = b"0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
# 特約商店商務代號
storeUid = "289151880002"
# 串接交易位置
url = "https://ka.usecase.cc/api/agent"
def getRawData(self):
"""取得串接欄位資料
Returns:
{dict}: 欄位資料
"""
rawData = {
'uid': "95217",
'key': "3425042d7d266e4aea5fd4653a0271db",
}
return rawData
def getService(self):
"""取得服務位置
Returns:
{dict}: 服務位置資料
"""
return {
'service_name': 'api',
'cmd': 'api/queryorder'
}
def encrypt(self, fields, key):
"""AES 256 加密
Args:
fields {dict}: 欄位資料
key {bytes}: AES金鑰
Returns:
{string}: 加密資料
"""
data = json.dumps(fields, separators=(',', ':'))
data = Padding.pad(data.encode('utf-8'), AES.block_size)
iv = get_random_bytes(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
data = cipher.encrypt(data)
data = base64.b64encode(iv + data)
return data
def post(self, postData):
"""資料 POST 到主機
Args:
postData {dict}: 欄位資料
Returns:
{string}: JSON資料
"""
result = requests.post(self.url, postData)
return result.text
def getPostData(self):
"""取得送出欄位資料
Returns:
{dict}: 欄位資料
"""
postData = {
'agent_uid': self.agentUid,
'service': self.encrypt(self.getService(), self.agentKey),
'encry_data': self.encrypt(self.getRawData(), self.agentKey)
}
return postData
def run(self):
"""執行
"""
json = self.post(self.getPostData())
print(json)
AgentQuery = AgentQuery()
AgentQuery.run()
回傳 JSON 結構如下:
{
"key": "c011e403fa73b088ca3d50aacfa9c43a",
"prc": "250",
"cardno": "493817******0003",
"acode": "AA1234",
"issuing_bank": "合作金庫",
"issuing_bank_uid": "006",
"is_agent_charge": 0,
"transaction_mode": 1,
"supplier_name": "高鉅金融",
"supplier_code": "T0",
"order_id": "20200227165CFAB2C9",
"user_id": "userid",
"uid": 59665,
"cost": 10,
"currency": "TWD",
"actual_cost": 10,
"actual_currency": "TWD",
"love_cost": 0,
"retmsg": "付款完成",
"pay_mode_uid": 1,
"pfn": "CREDITCARD",
"trans_type": 1,
"redeem": "",
"installment": "",
"finishtime": "20200227165436",
"store_group_id": "",
"nois": "",
"payment_name": "",
"bank_id": "",
"result_type": 4,
"result_content_type": "CREDITCARD",
"result_content": "{}",
"expired_date": "",
"appropriation_date": "20200318",
"invoice_state": 2,
"invoice_date": "20200227165440",
"invoice_wordtrack": "YJ",
"invoice_number": "00100030",
"invoice_rand_code": "",
"invoice_seller_ban": "",
"invoice_buyer_ban": "",
"invoice_left_qrcode": "",
"invoice_middle_barcode": "",
"invoice_right_qrcode": "",
"invoice_title_type": 1,
"invoice_title": "",
"invoice_amount": "0",
"invoice_sales_amount": "0",
"invoice_tax_amount": "0",
"invoice_order_detail": "[]",
"invoice_ratetype": 1,
"invoice_input_type": 2,
"invoice_allowance": [],
"echo_0": "",
"echo_1": "",
"echo_2": "",
"echo_3": "",
"echo_4": ""
}發動交易後,如果遲遲未接收回報,可透過此方法查詢訂單交易。
經銷商『交易查詢』參數說明
| 欄位 | 型態 | 說明 |
|---|---|---|
| agent_uid | string(16) | 經銷商商務代號 |
| service | text | {"service_name": "api", "cmd": "api\/queryorder"}JSON格式,AES256加密資料 |
| encry_data | text | 『交易查詢』欄位參考 JSON格式,AES256加密資料 |
『交易查詢』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| 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 | |
| invoice_count | int | 發票剩餘張數,只有打ka.usecase.cc和ka.mypay.tw才有 |
發動交易後,如果遲遲未接收回報,可透過此方法查詢訂單交易。
交易退款
<?php
/**
* 經銷商串接-交易退款
*/
final class AgentRefund
{
/**
* 經銷商商務代號
* @var string
*/
public $agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
* @var string
*/
public $agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號(代特約商店發動)
* @var string
*/
public $storeUid = "289151880002";
/**
* 串接交易位置
* @var string
*/
public $url = "https://ka.usecase.cc/api/agent";
/**
* 取得串接欄位資料
* @return array
*/
public function getRawData()
{
$rawData = array();
$rawData['store_uid'] = $this->storeUid;
$rawData['uid'] = "88833";
$rawData['key'] = "1c943777706d68f757afdb9034213001";
$rawData['cost'] = 100;
$rawData['invoice_state'] = 6;
$rawData['items'] = [
[
'id' => '1',
'name' => '倚天劍模型',
'cost' => 100,
'amount' => 1,
'total' => 100
]
];
return $rawData;
}
/**
* 取得服務位置
* @return array
*/
public function getService()
{
return array(
'service_name' => 'api',
'cmd' => 'api/refund'
);
}
/**
* AES 256 加密
* @param array $fields
* @param string $key
* @return string
*/
public 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;
}
/**
* 資料 POST 到主機
* @param array $postData
* @return mixed
*/
public function post($postData = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* 取得送出欄位資料
* @return array
*/
public function getPostData ()
{
$postData = array();
$postData['agent_uid'] = $this->agentUid;
$postData['service'] = $this->encrypt($this->getService(), $this->agentKey);
$postData['encry_data'] = $this->encrypt($this->getRawData(), $this->agentKey);
return $postData;
}
/**
* 執行
*/
public function run()
{
$json = $this->post($this->getPostData());
echo $json;
}
}
$AgentRefund = new AgentRefund();
$AgentRefund->run();
?>
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Dynamic;
/// <summary>
/// 建議使用.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也可能無法使用
/// </summary>
namespace MyPay {
/// <summary>
/// 經銷商串接-交易退款
/// </summary>
public class AgentRefund {
/// <summary>
/// 經銷商商務代號
/// </summary>
public string agentUid = "518169081001";
/// <summary>
/// 經銷商金鑰或認證碼
/// </summary>
public string agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/// <summary>
/// 特約商店商務代號
/// </summary>
public string storeUid = "289151880002";
/// <summary>
/// 串接交易位置
/// </summary>
public string url = "https://ka.usecase.cc/api/agent";
/// <summary>
/// 執行
/// </summary>
static void Main() {
AgentRefund simulator = new AgentRefund();
//僅限走https的Tls 1.2以上版本
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//發送至遠端
var result = simulator.Post(simulator.GetPostData());
System.Console.WriteLine(result);
}
/// <summary>
/// 取得串接欄位資料
/// </summary>
private dynamic GetRawData() {
ArrayList items = new ArrayList();
dynamic item = new ExpandoObject();
item.id = "1";
item.name = "倚天劍模型";
item.cost = 100;
item.amount = 1;
item.total = 100;
items.Add(item);
dynamic rawData = new ExpandoObject();
rawData.store_uid = this.storeUid;
rawData.uid = "88833";
rawData.key = "1c943777706d68f757afdb9034213001";
rawData.cost = 100;
rawData.invoice_state = 6;
rawData.items = items;
return rawData;
}
/// <summary>
/// 取得服務位置
/// </summary>
private ServiceRequest GetService() {
ServiceRequest rawData = new ServiceRequest();
rawData.service_name = "api";
rawData.cmd = "api/refund";
return rawData;
}
/// <summary>
/// 取得送出欄位資料
/// </summary>
private NameValueCollection GetPostData() {
string data_json = JsonConvert.SerializeObject(GetRawData(), Formatting.None);
string svr_json = JsonConvert.SerializeObject(GetService(), Formatting.None);; //依API種類調整
//產生AES向量
var IV = GetBytesIV();
//進行加密
var data_encode = Encrypt(data_json, this.agentKey, IV);
var svr_encode = Encrypt(svr_json, this.agentKey, IV);
//請注意使用的 Http Post 套件是否會自動加上UrlEncode,本Post範例為原始方式,故須加上UrlEncode
//若自行使用的套件會自動補上UrlEncode,則請忽略下面的UrlEncode,避免做了兩次UrlEncode
string data_toUrlEncode = HttpUtility.UrlEncode(data_encode);
string svr_toUrlEncode = HttpUtility.UrlEncode(svr_encode);
NameValueCollection postData = new NameValueCollection();
postData["agent_uid"] = this.agentUid;
postData["service"] = svr_toUrlEncode;
postData["encry_data"] = data_toUrlEncode;
return postData;
}
/// <summary>
/// AES 256 加密
/// </summary>
/// <param name="data"></param>
/// <param name="key"></param>
/// <param name="byteIV"></param>
/// <returns></returns>
private string Encrypt(string data, string key, byte[] byteIV) {
var byteKey = System.Text.Encoding.UTF8.GetBytes(key);
var enBytes = AES_Encrypt(data, byteKey, byteIV);
return Convert.ToBase64String(BytesAdd(byteIV, enBytes));
}
/// <summary>
/// AES 256 加密處理
/// </summary>
/// <param name="original"></param>
/// <param name="key"></param>
/// <param name="iv"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 轉換Bytes
/// </summary>
/// <param name="a"></param>
/// <param name="arryB"></param>
/// <returns></returns>
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();
}
/// <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;
}
/// <summary>
/// 資料 POST 到主機
/// </summary>
/// <param name="pars"></param>
/// <returns></returns>
private string Post(NameValueCollection pars) {
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(this.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>
/// 串接服務請求欄位
/// </summary>
public class ServiceRequest {
public string service_name { get; set; }
public string cmd { get; set; }
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URLEncoder;
import java.util.*;
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 static java.nio.charset.StandardCharsets.UTF_8;
import org.spongycastle.crypto.engines.AESEngine;
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 java.security.SecureRandom;
/**
* 經銷商串接-交易退款
* 1. jackson-core 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
* 2. jackson-databind 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
* 3. jackson-annotations 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
* 4. Spongy Castle 下載 https://mvnrepository.com/artifact/com.madgag.spongycastle/core
*/
public class AgentRefund {
/**
* 經銷商商務代號
*/
String agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
*/
String agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號
*/
String storeUid = "289151880002";
/**
* 串接交易位置
*/
String url = "https://ka.usecase.cc/api/agent";
/**
* 執行
* @param args
*/
public static void main(String[] args) {
AgentRefund simulator = new AgentRefund();
String json = simulator.post(simulator.getPostData());
System.out.print(json);
}
@SuppressWarnings(value = { "unchecked", "deprecation" })
/**
* 取得串接欄位資料
* @return 串接原始資料
*/
public Map getRawData() {
ArrayList items = new ArrayList();
Map<Object, Object> item = new HashMap<Object, Object>();
item.put("id", "1");
item.put("name", "倚天劍模型");
item.put("cost", 100);
item.put("amount", 1);
item.put("total", 100);
items.add(item);
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("store_uid", this.storeUid);
rawData.put("uid", "88833");
rawData.put("key", "1c943777706d68f757afdb9034213001");
rawData.put("cost", 100);
rawData.put("invoice_state", 6);
rawData.put("items", items);
return rawData;
}
/**
* 取得服務位置
* @return 串接服務資料
*/
public Map getService() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("service_name", "api");
rawData.put("cmd", "api/refund");
return rawData;
}
/**
* AES 256 加密
* @param rawData 原始資料
* @param AesKey AES256金鑰字串
* @return 轉換成Base64資料
*/
public String encrypt(Map rawData, String AesKey) {
try {
ObjectMapper objMapper = new ObjectMapper();
byte[] data = objMapper.writeValueAsString(rawData).getBytes(UTF_8);
byte[] key = AesKey.getBytes(UTF_8);
// 16 bytes is the IV size for AES256
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
// 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);
Base64.Encoder encoder = Base64.getEncoder();
String base64 = encoder.encodeToString(outBuf2);
return base64;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
/**
* 資料 POST 到主機
* @param qstr 串接資料
* @return 服務回傳JSON資訊
*/
public String post(String qstr) {
String result = "";
try {
// 資料
byte[] qstr_bytes = qstr.getBytes(StandardCharsets.UTF_8);
URL iurl = new URL(this.url);
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 + "\r\n");
}
try {
result = response.toString();
} finally {
in.close();
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return result;
}
/**
* 取得送出欄位資料
* @return POST完整資料
*/
public String getPostData() {
String postData = "";
try {
// Base64需要使用UrlEncode做傳輸
String data_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getRawData(), this.agentKey), "UTF-8");
String svr_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getService(), this.agentKey), "UTF-8");
postData = "agent_uid=" + this.agentUid + "&service="
+ svr_toUrlEncode + "&encry_data=" + data_toUrlEncode;
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return postData;
}
}
const crypto = require('crypto');
const httpRequest = require('https');
/**
* 經銷商串接-交易退款
*/
function AgentRefund() {
// 經銷商商務代號
this.agentUid = "518169081001";
// 經銷商金鑰或認證碼
this.agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
// 特約商店商務代號
this.storeUid = "289151880002";
// 串接交易位置
this.url = "https://ka.usecase.cc/api/agent";
};
/**
* 取得串接欄位資料
*/
AgentRefund.prototype.getRawData = function () {
return {
store_uid: this.storeUid,
uid: "88833",
key: "1c943777706d68f757afdb9034213001",
cost: 100,
invoice_state: 6,
items: [
{
'id': "1",
'name': "倚天劍模型",
'cost': 100,
'amount': 1,
'total': 100
}
],
};
};
/**
* 取得服務位置
*/
AgentRefund.prototype.getService = function () {
return {
service_name: "api",
cmd: "api/refund"
};
};
/**
* AES 256 加密
*/
AgentRefund.prototype.encrypt = function (fields, key) {
let eData = JSON.stringify(fields);
const blockSize = 16;
const iv = crypto.randomBytes(blockSize);
const encryptor = crypto.createCipheriv('aes-256-cbc', key, iv);
let tmpCipher = encryptor.update(Buffer.from(eData));
let finalCipher = encryptor.final();
const tempData = Buffer.concat([tmpCipher, finalCipher], tmpCipher.length + finalCipher.length);
let data = Buffer.concat([iv, tempData], iv.length + tempData.length).toString('base64');
return data;
};
/**
* 資料 POST 到主機
*/
AgentRefund.prototype.post = function (postData) {
return new Promise((res, rej) => {
let options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
rejectUnauthorized: false
};
let send_process = httpRequest.request(this.url, options, (api_res) => {
let res_data = "";
api_res.on('data', (tmp_data) => {
res_data += tmp_data;
});
api_res.on('end', () => {
res(res_data);
});
});
send_process.write(JSON.stringify(postData));
send_process.end();
});
};
/**
* 取得送出欄位資料
*/
AgentRefund.prototype.getPostData = function () {
return {
"agent_uid": this.agentUid,
"service": this.encrypt(this.getService(), this.agentKey),
"encry_data": this.encrypt(this.getRawData(), this.agentKey)
};
};
/**
* 執行
*/
AgentRefund.prototype.run = async function () {
json = await this.post(this.getPostData())
console.log(json);
};
AgentRefund = new AgentRefund();
AgentRefund.run();
# -*- coding: utf-8 -*-
import json
import base64
import requests
from Crypto.Cipher import AES
from Crypto.Util import Padding
from Crypto.Random import get_random_bytes
"""經銷商串接-交易退款
"""
class AgentRefund:
# 經銷商商務代號
agentUid = "518169081001";
# 經銷商金鑰或認證碼
agentKey = b"0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
# 特約商店商務代號
storeUid = "289151880002"
# 串接交易位置
url = "https://ka.usecase.cc/api/agent"
def getRawData(self):
"""取得串接欄位資料
Returns:
{dict}: 欄位資料
"""
rawData = {
'store_uid': self.storeUid,
'uid': "88833",
'key': "1c943777706d68f757afdb9034213001",
'cost': 100,
'invoice_state': 6,
'items': [
{
'id': "1",
'name': "倚天劍模型",
'cost': 100,
'amount': 1,
'total': 100
}
],
}
return rawData
def getService(self):
"""取得服務位置
Returns:
{dict}: 服務位置資料
"""
return {
'service_name': 'api',
'cmd': 'api/refund'
}
def encrypt(self, fields, key):
"""AES 256 加密
Args:
fields {dict}: 欄位資料
key {bytes}: AES金鑰
Returns:
{string}: 加密資料
"""
data = json.dumps(fields, separators=(',', ':'))
data = Padding.pad(data.encode('utf-8'), AES.block_size)
iv = get_random_bytes(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
data = cipher.encrypt(data)
data = base64.b64encode(iv + data)
return data
def post(self, postData):
"""資料 POST 到主機
Args:
postData {dict}: 欄位資料
Returns:
{string}: JSON資料
"""
result = requests.post(self.url, postData)
return result.text
def getPostData(self):
"""取得送出欄位資料
Returns:
{dict}: 欄位資料
"""
postData = {
'agent_uid': self.agentUid,
'service': self.encrypt(self.getService(), self.agentKey),
'encry_data': self.encrypt(self.getRawData(), self.agentKey)
}
return postData
def run(self):
"""執行
"""
json = self.post(self.getPostData())
print(json)
AgentRefund = AgentRefund()
AgentRefund.run()
回傳 JSON 結構如下:
{
"row_data": {
"uid": 88833,
"refund_uid": 88834,
"key": "1c943777706d68f757afdb9034213001",
"prc": "230",
"finishtime": "20210701104600",
"order_id": "20210701107C23AA66",
"user_id": "userid",
"cost": 100,
"currency": "TWD",
"actual_cost": 100,
"actual_currency": "TWD",
"retmsg": "退款完成",
"pfn": "CREDITCARD",
"payment_name": "",
"nois": "",
"group_id": "",
"refund_type": 1,
"expected_refund_date": "",
"echo_0": "",
"echo_1": "",
"echo_2": "",
"echo_3": "",
"echo_4": ""
},
"key": "1c943777706d68f757afdb9034213001",
"uid": "88833",
"code": "B200",
"msg": "執行成功"
}若需要退款時,發動此API提出退款請求。支援即時退款且未超過退款期限內之支付方式皆可使用此方式發動退款。 支援即時退款的支付方式有信用卡、美國運通、LINEPay、Pi錢包、街口支付、微信支付、支付寶、悠遊付、現金、GooglePay、ApplePay。
經銷商『交易退款』參數說明
| 欄位 | 型態 | 說明 |
|---|---|---|
| agent_uid | string(16) | 經銷商商務代號 |
| service | text | {"service_name": "api", "cmd": "api\/refund"}JSON格式,AES256加密資料 |
| encry_data | text | 『交易退款』欄位參考 JSON格式,AES256加密資料 |
『交易退款』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| store_uid | string | 特約商店代碼 | |
| key | string | 交易驗証碼 | |
| uid | string | 訂單編號(UID) | |
| cost | string | 退款金額(可部分退款) | |
| invoice_state | integer | 若有開立電子發票,指定電子發票使用作廢或折讓 注意:跨發票月份無法作廢 | 『電子發票退款時使用作廢或折讓』值參考 |
| items | array | 退款項目,全額退款時可以不用帶入此欄位 1.若使用電子發票,此欄位必填 2.退款項目之項目名稱必須和交易時之產品項目名稱相同 3.退款項目之總金額必須與退款金額一致 4.同時滿足"交易訂單有發票"、"使用discount"、"非全額退款",退款時,若要取消折扣,則要自帶一個項目,名稱為折扣 | 每筆『商品項目』欄位參考 |
『交易退款』回傳欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| key | string | 特約商店驗證碼 (store_token) | |
| uid | string | 訂單編號(UID) | |
| code | string | 處理狀態 B200 或 B500 | |
| msg | string | 回傳訊息 | |
| row_data | object | 退款資訊(即時退款才有此資訊) | 『退款完成回傳資訊』欄位參考 |
信用卡取消授權
<?php
/**
* 經銷商串接-信用卡取消授權
*/
final class AgentCreditcardCancelAuthorized
{
/**
* 經銷商商務代號
* @var string
*/
public $agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
* @var string
*/
public $agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號(代特約商店發動)
* @var string
*/
public $storeUid = "289151880002";
/**
* 串接交易位置
* @var string
*/
public $url = "https://ka.usecase.cc/api/agent";
/**
* 取得串接欄位資料
* @return array
*/
public function getRawData()
{
$rawData = array();
$rawData['store_uid'] = $this->storeUid;
$rawData['uid'] = "103274";
$rawData['key'] = "c1482acd0f7b459ee17b12c29660d582";
return $rawData;
}
/**
* 取得服務位置
* @return array
*/
public function getService()
{
return array(
'service_name' => 'api',
'cmd' => 'api/cancelauthorization'
);
}
/**
* AES 256 加密
* @param array $fields
* @param string $key
* @return string
*/
public 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;
}
/**
* 資料 POST 到主機
* @param array $postData
* @return mixed
*/
public function post($postData = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* 取得送出欄位資料
* @return array
*/
public function getPostData ()
{
$postData = array();
$postData['agent_uid'] = $this->agentUid;
$postData['service'] = $this->encrypt($this->getService(), $this->agentKey);
$postData['encry_data'] = $this->encrypt($this->getRawData(), $this->agentKey);
return $postData;
}
/**
* 執行
*/
public function run()
{
$json = $this->post($this->getPostData());
echo $json;
}
}
$AgentCreditcardCancelAuthorized = new AgentCreditcardCancelAuthorized();
$AgentCreditcardCancelAuthorized->run();
?>
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Dynamic;
/// <summary>
/// 建議使用.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也可能無法使用
/// </summary>
namespace MyPay {
/// <summary>
/// 經銷商串接-信用卡取消授權
/// </summary>
public class AgentCreditcardCancelAuthorized {
/// <summary>
/// 經銷商商務代號
/// </summary>
public string agentUid = "518169081001";
/// <summary>
/// 經銷商金鑰或認證碼
/// </summary>
public string agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/// <summary>
/// 特約商店商務代號
/// </summary>
public string storeUid = "289151880002";
/// <summary>
/// 串接交易位置
/// </summary>
public string url = "https://ka.usecase.cc/api/agent";
/// <summary>
/// 執行
/// </summary>
static void Main() {
AgentCreditcardCancelAuthorized simulator = new AgentCreditcardCancelAuthorized();
//僅限走https的Tls 1.2以上版本
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//發送至遠端
var result = simulator.Post(simulator.GetPostData());
System.Console.WriteLine(result);
}
/// <summary>
/// 取得串接欄位資料
/// </summary>
private dynamic GetRawData() {
dynamic rawData = new ExpandoObject();
rawData.store_uid = this.storeUid;
rawData.uid = "103274";
rawData.key = "c1482acd0f7b459ee17b12c29660d582";
return rawData;
}
/// <summary>
/// 取得服務位置
/// </summary>
private ServiceRequest GetService() {
ServiceRequest rawData = new ServiceRequest();
rawData.service_name = "api";
rawData.cmd = "api/cancelauthorization";
return rawData;
}
/// <summary>
/// 取得送出欄位資料
/// </summary>
private NameValueCollection GetPostData() {
string data_json = JsonConvert.SerializeObject(GetRawData(), Formatting.None);
string svr_json = JsonConvert.SerializeObject(GetService(), Formatting.None);; //依API種類調整
//產生AES向量
var IV = GetBytesIV();
//進行加密
var data_encode = Encrypt(data_json, this.agentKey, IV);
var svr_encode = Encrypt(svr_json, this.agentKey, IV);
//請注意使用的 Http Post 套件是否會自動加上UrlEncode,本Post範例為原始方式,故須加上UrlEncode
//若自行使用的套件會自動補上UrlEncode,則請忽略下面的UrlEncode,避免做了兩次UrlEncode
string data_toUrlEncode = HttpUtility.UrlEncode(data_encode);
string svr_toUrlEncode = HttpUtility.UrlEncode(svr_encode);
NameValueCollection postData = new NameValueCollection();
postData["agent_uid"] = this.agentUid;
postData["service"] = svr_toUrlEncode;
postData["encry_data"] = data_toUrlEncode;
return postData;
}
/// <summary>
/// AES 256 加密
/// </summary>
/// <param name="data"></param>
/// <param name="key"></param>
/// <param name="byteIV"></param>
/// <returns></returns>
private string Encrypt(string data, string key, byte[] byteIV) {
var byteKey = System.Text.Encoding.UTF8.GetBytes(key);
var enBytes = AES_Encrypt(data, byteKey, byteIV);
return Convert.ToBase64String(BytesAdd(byteIV, enBytes));
}
/// <summary>
/// AES 256 加密處理
/// </summary>
/// <param name="original"></param>
/// <param name="key"></param>
/// <param name="iv"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 轉換Bytes
/// </summary>
/// <param name="a"></param>
/// <param name="arryB"></param>
/// <returns></returns>
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();
}
/// <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;
}
/// <summary>
/// 資料 POST 到主機
/// </summary>
/// <param name="pars"></param>
/// <returns></returns>
private string Post(NameValueCollection pars) {
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(this.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>
/// 串接服務請求欄位
/// </summary>
public class ServiceRequest {
public string service_name { get; set; }
public string cmd { get; set; }
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URLEncoder;
import java.util.*;
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 static java.nio.charset.StandardCharsets.UTF_8;
import org.spongycastle.crypto.engines.AESEngine;
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 java.security.SecureRandom;
/**
* 經銷商串接-信用卡取消授權
* 1. jackson-core 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
* 2. jackson-databind 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
* 3. jackson-annotations 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
* 4. Spongy Castle 下載 https://mvnrepository.com/artifact/com.madgag.spongycastle/core
*/
public class AgentCreditcardCancelAuthorized {
/**
* 經銷商商務代號
*/
String agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
*/
String agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號
*/
String storeUid = "289151880002";
/**
* 串接交易位置
*/
String url = "https://ka.usecase.cc/api/agent";
/**
* 執行
* @param args
*/
public static void main(String[] args) {
AgentCreditcardCancelAuthorized simulator = new AgentCreditcardCancelAuthorized();
String json = simulator.post(simulator.getPostData());
System.out.print(json);
}
@SuppressWarnings(value = { "unchecked", "deprecation" })
/**
* 取得串接欄位資料
* @return 串接原始資料
*/
public Map getRawData() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("store_uid", this.storeUid);
rawData.put("uid", "103274");
rawData.put("key", "c1482acd0f7b459ee17b12c29660d582");
return rawData;
}
/**
* 取得服務位置
* @return 串接服務資料
*/
public Map getService() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("service_name", "api");
rawData.put("cmd", "api/cancelauthorization");
return rawData;
}
/**
* AES 256 加密
* @param rawData 原始資料
* @param AesKey AES256金鑰字串
* @return 轉換成Base64資料
*/
public String encrypt(Map rawData, String AesKey) {
try {
ObjectMapper objMapper = new ObjectMapper();
byte[] data = objMapper.writeValueAsString(rawData).getBytes(UTF_8);
byte[] key = AesKey.getBytes(UTF_8);
// 16 bytes is the IV size for AES256
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
// 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);
Base64.Encoder encoder = Base64.getEncoder();
String base64 = encoder.encodeToString(outBuf2);
return base64;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
/**
* 資料 POST 到主機
* @param qstr 串接資料
* @return 服務回傳JSON資訊
*/
public String post(String qstr) {
String result = "";
try {
// 資料
byte[] qstr_bytes = qstr.getBytes(StandardCharsets.UTF_8);
URL iurl = new URL(this.url);
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 + "\r\n");
}
try {
result = response.toString();
} finally {
in.close();
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return result;
}
/**
* 取得送出欄位資料
* @return POST完整資料
*/
public String getPostData() {
String postData = "";
try {
// Base64需要使用UrlEncode做傳輸
String data_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getRawData(), this.agentKey), "UTF-8");
String svr_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getService(), this.agentKey), "UTF-8");
postData = "agent_uid=" + this.agentUid + "&service="
+ svr_toUrlEncode + "&encry_data=" + data_toUrlEncode;
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return postData;
}
}
const crypto = require('crypto');
const httpRequest = require('https');
/**
* 經銷商串接-信用卡取消授權
*/
function AgentCreditcardCancelAuthorized() {
// 經銷商商務代號
this.agentUid = "518169081001";
// 經銷商金鑰或認證碼
this.agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
// 特約商店商務代號
this.storeUid = "289151880002";
// 串接交易位置
this.url = "https://ka.usecase.cc/api/agent";
};
/**
* 取得串接欄位資料
*/
AgentCreditcardCancelAuthorized.prototype.getRawData = function () {
return {
store_uid: this.storeUid,
uid: "103274",
key: "c1482acd0f7b459ee17b12c29660d582",
};
};
/**
* 取得服務位置
*/
AgentCreditcardCancelAuthorized.prototype.getService = function () {
return {
service_name: "api",
cmd: "api/cancelauthorization"
};
};
/**
* AES 256 加密
*/
AgentCreditcardCancelAuthorized.prototype.encrypt = function (fields, key) {
let eData = JSON.stringify(fields);
const blockSize = 16;
const iv = crypto.randomBytes(blockSize);
const encryptor = crypto.createCipheriv('aes-256-cbc', key, iv);
let tmpCipher = encryptor.update(Buffer.from(eData));
let finalCipher = encryptor.final();
const tempData = Buffer.concat([tmpCipher, finalCipher], tmpCipher.length + finalCipher.length);
let data = Buffer.concat([iv, tempData], iv.length + tempData.length).toString('base64');
return data;
};
/**
* 資料 POST 到主機
*/
AgentCreditcardCancelAuthorized.prototype.post = function (postData) {
return new Promise((res, rej) => {
let options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
rejectUnauthorized: false
};
let send_process = httpRequest.request(this.url, options, (api_res) => {
let res_data = "";
api_res.on('data', (tmp_data) => {
res_data += tmp_data;
});
api_res.on('end', () => {
res(res_data);
});
});
send_process.write(JSON.stringify(postData));
send_process.end();
});
};
/**
* 取得送出欄位資料
*/
AgentCreditcardCancelAuthorized.prototype.getPostData = function () {
return {
"agent_uid": this.agentUid,
"service": this.encrypt(this.getService(), this.agentKey),
"encry_data": this.encrypt(this.getRawData(), this.agentKey)
};
};
/**
* 執行
*/
AgentCreditcardCancelAuthorized.prototype.run = async function () {
json = await this.post(this.getPostData())
console.log(json);
};
AgentCreditcardCancelAuthorized = new AgentCreditcardCancelAuthorized();
AgentCreditcardCancelAuthorized.run();
# -*- coding: utf-8 -*-
import json
import base64
import requests
from Crypto.Cipher import AES
from Crypto.Util import Padding
from Crypto.Random import get_random_bytes
"""經銷商串接-信用卡取消授權
"""
class AgentCreditcardCancelAuthorized:
# 經銷商商務代號
agentUid = "518169081001";
# 經銷商金鑰或認證碼
agentKey = b"0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
# 特約商店商務代號
storeUid = "289151880002"
# 串接交易位置
url = "https://ka.usecase.cc/api/agent"
def getRawData(self):
"""取得串接欄位資料
Returns:
{dict}: 欄位資料
"""
rawData = {
'store_uid': self.storeUid,
'uid': "103274",
'key': "c1482acd0f7b459ee17b12c29660d582",
}
return rawData
def getService(self):
"""取得服務位置
Returns:
{dict}: 服務位置資料
"""
return {
'service_name': 'api',
'cmd': 'api/cancelauthorization'
}
def encrypt(self, fields, key):
"""AES 256 加密
Args:
fields {dict}: 欄位資料
key {bytes}: AES金鑰
Returns:
{string}: 加密資料
"""
data = json.dumps(fields, separators=(',', ':'))
data = Padding.pad(data.encode('utf-8'), AES.block_size)
iv = get_random_bytes(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
data = cipher.encrypt(data)
data = base64.b64encode(iv + data)
return data
def post(self, postData):
"""資料 POST 到主機
Args:
postData {dict}: 欄位資料
Returns:
{string}: JSON資料
"""
result = requests.post(self.url, postData)
return result.text
def getPostData(self):
"""取得送出欄位資料
Returns:
{dict}: 欄位資料
"""
postData = {
'agent_uid': self.agentUid,
'service': self.encrypt(self.getService(), self.agentKey),
'encry_data': self.encrypt(self.getRawData(), self.agentKey)
}
return postData
def run(self):
"""執行
"""
json = self.post(self.getPostData())
print(json)
AgentCreditcardCancelAuthorized = AgentCreditcardCancelAuthorized()
AgentCreditcardCancelAuthorized.run()
回傳 JSON 結構如下:
{
"code": "B200",
"msg": "執行成功,取消授權完成",
"content": {
"key": "c1482acd0f7b459ee17b12c29660d582",
"prc": "300",
"cardno": "493817******0003",
"acode": "185804",
"card_type": "1",
"issuing_bank": "合作金庫",
"issuing_bank_uid": "006",
"transaction_mode": 1,
"supplier_name": "凱基銀行",
"supplier_code": "BC",
"order_id": "1234567890",
"user_id": "phper",
"uid": 103274,
"cost": 10,
"currency": "TWD",
"actual_cost": 10,
"actual_currency": "TWD",
"voucher_paid": [],
"voucher_free": [],
"price": 0,
"actual_price": 0,
"recharge_code": "",
"love_cost": 0,
"retmsg": "交易失敗",
"pay_mode_uid": 1,
"pfn": "CREDITCARD",
"trans_type": 1,
"redeem": "",
"installment": "",
"finishtime": "",
"store_group_id": "",
"group_id": "",
"nois": "",
"payment_name": "",
"bank_id": "",
"result_type": 4,
"result_content_type": "CREDITCARD",
"result_content": "{}",
"expired_date": "",
"appropriation_date": "",
"invoice_state": 0,
"invoice_date": "20220301151856",
"invoice_wordtrack": "JH",
"invoice_number": "00000011",
"invoice_rand_code": "9899",
"invoice_seller_ban": "28915188",
"invoice_buyer_ban": "",
"invoice_left_qrcode": "JH00000011111030198990000000a0000000a0000000028915188qKBLmT8adunB+e9m7isLNQ==:**********:1:1:1:倚天劍模型:1:10:",
"invoice_middle_barcode": "11104JH000000119899",
"invoice_right_qrcode": "**",
"invoice_title_type": 1,
"invoice_title": "123",
"invoice_print_type": 0,
"invoice_print_device": 0,
"invoice_amount": "10",
"invoice_sales_amount": "10",
"invoice_tax_amount": "0",
"invoice_order_detail": "[{\"Description\":\"倚天劍模型\",\"Quantity\":\"1\",\"UnitPrice\":\"10\",\"Amount\":\"10\"}]",
"invoice_ratetype": 1,
"invoice_input_type": 1,
"invoice_cloud_type": 2,
"invoice_mobile_code": "\/NFVIAZP",
"invoice_tax_id": "",
"invoice_natural_person": "",
"invoice_love_code": "",
"invoice_b2b_title": "",
"invoice_b2b_id": "",
"invoice_b2b_post_zone": "",
"invoice_b2b_address": "",
"invoice_allowance": [
{
"uid": 103274,
"amount": "10",
"order_detail": "[{\"SeqNo\":\"0\",\"ItemID\":\"103274\",\"ItemName\":\"倚天劍模型\",\"Qty\":\"1\",\"TotalAmount\":\"10\",\"RateType\":\"1\"}]"
}
],
"refund_order": [],
"cancel_order": [],
"echo_0": "",
"echo_1": "",
"echo_2": "",
"echo_3": "",
"echo_4": ""
}
}信用卡類交易,若使用自行請款模式,當交易狀態為授權完成(245)時,則可以發動此信用卡來進行取消授權,用以取消交易,並釋出消費者圈存金額。
經銷商『信用卡取消授權』參數說明
| 欄位 | 型態 | 說明 |
|---|---|---|
| agent_uid | string(16) | 經銷商商務代號 |
| service | text | {"service_name": "api", "cmd": "api\/cancelauthorization"}JSON格式,AES256加密資料 |
| encry_data | text | 『信用卡取消授權』欄位參考 JSON格式,AES256加密資料 |
『信用卡取消授權』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| store_uid | string | 特約商店編號 | 必填 |
| uid | string | 交易流水號 | |
| key | string | 交易驗証碼 |
『信用卡取消授權』回傳欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| code | string | 交易回傳碼 | |
| msg | string | 回傳訊息 | |
| content | object | 查詢內容 | 『交易查詢』欄位參考 |
信用卡授權請款
<?php
/**
* 經銷商串接-信用卡授權請款
*/
final class AgentCreditcardRequestPayment
{
/**
* 經銷商商務代號
* @var string
*/
public $agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
* @var string
*/
public $agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號(代特約商店發動)
* @var string
*/
public $storeUid = "289151880002";
/**
* 串接交易位置
* @var string
*/
public $url = "https://ka.usecase.cc/api/agent";
/**
* 取得串接欄位資料
* @return array
*/
public function getRawData()
{
$rawData = array();
$rawData['store_uid'] = $this->storeUid;
$rawData['uid'] = "103283";
$rawData['key'] = "54886f30612771f8f10d94499a41a347";
$rawData['cost'] = 9;
$rawData['items'] = [
[
'id' => '1',
'name' => '商品名稱',
'cost' => '9',
'amount' => '1',
'total' => '9'
]
];
return $rawData;
}
/**
* 取得服務位置
* @return array
*/
public function getService()
{
return array(
'service_name' => 'api',
'cmd' => 'api/authorizedrequestpayment'
);
}
/**
* AES 256 加密
* @param array $fields
* @param string $key
* @return string
*/
public 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;
}
/**
* 資料 POST 到主機
* @param array $postData
* @return mixed
*/
public function post($postData = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* 取得送出欄位資料
* @return array
*/
public function getPostData ()
{
$postData = array();
$postData['agent_uid'] = $this->agentUid;
$postData['service'] = $this->encrypt($this->getService(), $this->agentKey);
$postData['encry_data'] = $this->encrypt($this->getRawData(), $this->agentKey);
return $postData;
}
/**
* 執行
*/
public function run()
{
$json = $this->post($this->getPostData());
echo $json;
}
}
$AgentCreditcardRequestPayment = new AgentCreditcardRequestPayment();
$AgentCreditcardRequestPayment->run();
?>
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Dynamic;
/// <summary>
/// 建議使用.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也可能無法使用
/// </summary>
namespace MyPay {
/// <summary>
/// 經銷商串接-信用卡授權請款
/// </summary>
public class AgentCreditcardRequestPayment {
/// <summary>
/// 經銷商商務代號
/// </summary>
public string agentUid = "518169081001";
/// <summary>
/// 經銷商金鑰或認證碼
/// </summary>
public string agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/// <summary>
/// 特約商店商務代號
/// </summary>
public string storeUid = "289151880002";
/// <summary>
/// 串接交易位置
/// </summary>
public string url = "https://ka.usecase.cc/api/agent";
/// <summary>
/// 執行
/// </summary>
static void Main() {
AgentCreditcardRequestPayment simulator = new AgentCreditcardRequestPayment();
//僅限走https的Tls 1.2以上版本
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//發送至遠端
var result = simulator.Post(simulator.GetPostData());
System.Console.WriteLine(result);
}
/// <summary>
/// 取得串接欄位資料
/// </summary>
private dynamic GetRawData() {
ArrayList items = new ArrayList();
dynamic item = new ExpandoObject();
item.id = "1";
item.name = "商品名稱";
item.cost = "9";
item.amount = "1";
item.total = "9";
items.Add(item);
dynamic rawData = new ExpandoObject();
rawData.store_uid = this.storeUid;
rawData.uid = "103283";
rawData.key = "54886f30612771f8f10d94499a41a347";
rawData.cost = 9;
rawData.items = items;
return rawData;
}
/// <summary>
/// 取得服務位置
/// </summary>
private ServiceRequest GetService() {
ServiceRequest rawData = new ServiceRequest();
rawData.service_name = "api";
rawData.cmd = "api/authorizedrequestpayment";
return rawData;
}
/// <summary>
/// 取得送出欄位資料
/// </summary>
private NameValueCollection GetPostData() {
string data_json = JsonConvert.SerializeObject(GetRawData(), Formatting.None);
string svr_json = JsonConvert.SerializeObject(GetService(), Formatting.None);; //依API種類調整
//產生AES向量
var IV = GetBytesIV();
//進行加密
var data_encode = Encrypt(data_json, this.agentKey, IV);
var svr_encode = Encrypt(svr_json, this.agentKey, IV);
//請注意使用的 Http Post 套件是否會自動加上UrlEncode,本Post範例為原始方式,故須加上UrlEncode
//若自行使用的套件會自動補上UrlEncode,則請忽略下面的UrlEncode,避免做了兩次UrlEncode
string data_toUrlEncode = HttpUtility.UrlEncode(data_encode);
string svr_toUrlEncode = HttpUtility.UrlEncode(svr_encode);
NameValueCollection postData = new NameValueCollection();
postData["agent_uid"] = this.agentUid;
postData["service"] = svr_toUrlEncode;
postData["encry_data"] = data_toUrlEncode;
return postData;
}
/// <summary>
/// AES 256 加密
/// </summary>
/// <param name="data"></param>
/// <param name="key"></param>
/// <param name="byteIV"></param>
/// <returns></returns>
private string Encrypt(string data, string key, byte[] byteIV) {
var byteKey = System.Text.Encoding.UTF8.GetBytes(key);
var enBytes = AES_Encrypt(data, byteKey, byteIV);
return Convert.ToBase64String(BytesAdd(byteIV, enBytes));
}
/// <summary>
/// AES 256 加密處理
/// </summary>
/// <param name="original"></param>
/// <param name="key"></param>
/// <param name="iv"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 轉換Bytes
/// </summary>
/// <param name="a"></param>
/// <param name="arryB"></param>
/// <returns></returns>
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();
}
/// <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;
}
/// <summary>
/// 資料 POST 到主機
/// </summary>
/// <param name="pars"></param>
/// <returns></returns>
private string Post(NameValueCollection pars) {
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(this.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>
/// 串接服務請求欄位
/// </summary>
public class ServiceRequest {
public string service_name { get; set; }
public string cmd { get; set; }
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URLEncoder;
import java.util.*;
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 static java.nio.charset.StandardCharsets.UTF_8;
import org.spongycastle.crypto.engines.AESEngine;
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 java.security.SecureRandom;
/**
* 經銷商串接-信用卡授權請款
* 1. jackson-core 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
* 2. jackson-databind 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
* 3. jackson-annotations 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
* 4. Spongy Castle 下載 https://mvnrepository.com/artifact/com.madgag.spongycastle/core
*/
public class AgentCreditcardRequestPayment {
/**
* 經銷商商務代號
*/
String agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
*/
String agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號
*/
String storeUid = "289151880002";
/**
* 串接交易位置
*/
String url = "https://ka.usecase.cc/api/agent";
/**
* 執行
* @param args
*/
public static void main(String[] args) {
AgentCreditcardRequestPayment simulator = new AgentCreditcardRequestPayment();
String json = simulator.post(simulator.getPostData());
System.out.print(json);
}
@SuppressWarnings(value = { "unchecked", "deprecation" })
/**
* 取得串接欄位資料
* @return 串接原始資料
*/
public Map getRawData() {
ArrayList items = new ArrayList();
Map<Object, Object> item = new HashMap<Object, Object>();
item.put("id", "1");
item.put("name", "商品名稱");
item.put("cost", "9");
item.put("amount", "1");
item.put("total", "9");
items.add(item);
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("store_uid", this.storeUid);
rawData.put("uid", "103283");
rawData.put("key", "54886f30612771f8f10d94499a41a347");
rawData.put("cost", 9);
rawData.put("items", items);
return rawData;
}
/**
* 取得服務位置
* @return 串接服務資料
*/
public Map getService() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("service_name", "api");
rawData.put("cmd", "api/authorizedrequestpayment");
return rawData;
}
/**
* AES 256 加密
* @param rawData 原始資料
* @param AesKey AES256金鑰字串
* @return 轉換成Base64資料
*/
public String encrypt(Map rawData, String AesKey) {
try {
ObjectMapper objMapper = new ObjectMapper();
byte[] data = objMapper.writeValueAsString(rawData).getBytes(UTF_8);
byte[] key = AesKey.getBytes(UTF_8);
// 16 bytes is the IV size for AES256
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
// 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);
Base64.Encoder encoder = Base64.getEncoder();
String base64 = encoder.encodeToString(outBuf2);
return base64;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
/**
* 資料 POST 到主機
* @param qstr 串接資料
* @return 服務回傳JSON資訊
*/
public String post(String qstr) {
String result = "";
try {
// 資料
byte[] qstr_bytes = qstr.getBytes(StandardCharsets.UTF_8);
URL iurl = new URL(this.url);
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 + "\r\n");
}
try {
result = response.toString();
} finally {
in.close();
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return result;
}
/**
* 取得送出欄位資料
* @return POST完整資料
*/
public String getPostData() {
String postData = "";
try {
// Base64需要使用UrlEncode做傳輸
String data_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getRawData(), this.agentKey), "UTF-8");
String svr_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getService(), this.agentKey), "UTF-8");
postData = "agent_uid=" + this.agentUid + "&service="
+ svr_toUrlEncode + "&encry_data=" + data_toUrlEncode;
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return postData;
}
}
const crypto = require('crypto');
const httpRequest = require('https');
/**
* 經銷商串接-信用卡授權請款
*/
function AgentCreditcardRequestPayment() {
// 經銷商商務代號
this.agentUid = "518169081001";
// 經銷商金鑰或認證碼
this.agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
// 特約商店商務代號
this.storeUid = "289151880002";
// 串接交易位置
this.url = "https://ka.usecase.cc/api/agent";
};
/**
* 取得串接欄位資料
*/
AgentCreditcardRequestPayment.prototype.getRawData = function () {
return {
store_uid: this.storeUid,
uid: "103283",
key: "54886f30612771f8f10d94499a41a347",
cost: 9,
items: [
{
'id': "1",
'name': "商品名稱",
'cost': "9",
'amount': "1",
'total': "9"
}
],
};
};
/**
* 取得服務位置
*/
AgentCreditcardRequestPayment.prototype.getService = function () {
return {
service_name: "api",
cmd: "api/authorizedrequestpayment"
};
};
/**
* AES 256 加密
*/
AgentCreditcardRequestPayment.prototype.encrypt = function (fields, key) {
let eData = JSON.stringify(fields);
const blockSize = 16;
const iv = crypto.randomBytes(blockSize);
const encryptor = crypto.createCipheriv('aes-256-cbc', key, iv);
let tmpCipher = encryptor.update(Buffer.from(eData));
let finalCipher = encryptor.final();
const tempData = Buffer.concat([tmpCipher, finalCipher], tmpCipher.length + finalCipher.length);
let data = Buffer.concat([iv, tempData], iv.length + tempData.length).toString('base64');
return data;
};
/**
* 資料 POST 到主機
*/
AgentCreditcardRequestPayment.prototype.post = function (postData) {
return new Promise((res, rej) => {
let options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
rejectUnauthorized: false
};
let send_process = httpRequest.request(this.url, options, (api_res) => {
let res_data = "";
api_res.on('data', (tmp_data) => {
res_data += tmp_data;
});
api_res.on('end', () => {
res(res_data);
});
});
send_process.write(JSON.stringify(postData));
send_process.end();
});
};
/**
* 取得送出欄位資料
*/
AgentCreditcardRequestPayment.prototype.getPostData = function () {
return {
"agent_uid": this.agentUid,
"service": this.encrypt(this.getService(), this.agentKey),
"encry_data": this.encrypt(this.getRawData(), this.agentKey)
};
};
/**
* 執行
*/
AgentCreditcardRequestPayment.prototype.run = async function () {
json = await this.post(this.getPostData())
console.log(json);
};
AgentCreditcardRequestPayment = new AgentCreditcardRequestPayment();
AgentCreditcardRequestPayment.run();
# -*- coding: utf-8 -*-
import json
import base64
import requests
from Crypto.Cipher import AES
from Crypto.Util import Padding
from Crypto.Random import get_random_bytes
"""經銷商串接-信用卡授權請款
"""
class AgentCreditcardRequestPayment:
# 經銷商商務代號
agentUid = "518169081001";
# 經銷商金鑰或認證碼
agentKey = b"0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
# 特約商店商務代號
storeUid = "289151880002"
# 串接交易位置
url = "https://ka.usecase.cc/api/agent"
def getRawData(self):
"""取得串接欄位資料
Returns:
{dict}: 欄位資料
"""
rawData = {
'store_uid': self.storeUid,
'uid': "103283",
'key': "54886f30612771f8f10d94499a41a347",
'cost': 9,
'items': [
{
'id': "1",
'name': "商品名稱",
'cost': "9",
'amount': "1",
'total': "9"
}
],
}
return rawData
def getService(self):
"""取得服務位置
Returns:
{dict}: 服務位置資料
"""
return {
'service_name': 'api',
'cmd': 'api/authorizedrequestpayment'
}
def encrypt(self, fields, key):
"""AES 256 加密
Args:
fields {dict}: 欄位資料
key {bytes}: AES金鑰
Returns:
{string}: 加密資料
"""
data = json.dumps(fields, separators=(',', ':'))
data = Padding.pad(data.encode('utf-8'), AES.block_size)
iv = get_random_bytes(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
data = cipher.encrypt(data)
data = base64.b64encode(iv + data)
return data
def post(self, postData):
"""資料 POST 到主機
Args:
postData {dict}: 欄位資料
Returns:
{string}: JSON資料
"""
result = requests.post(self.url, postData)
return result.text
def getPostData(self):
"""取得送出欄位資料
Returns:
{dict}: 欄位資料
"""
postData = {
'agent_uid': self.agentUid,
'service': self.encrypt(self.getService(), self.agentKey),
'encry_data': self.encrypt(self.getRawData(), self.agentKey)
}
return postData
def run(self):
"""執行
"""
json = self.post(self.getPostData())
print(json)
AgentCreditcardRequestPayment = AgentCreditcardRequestPayment()
AgentCreditcardRequestPayment.run()
回傳 JSON 結構如下:
{
"code": "B200",
"msg": "執行成功,請款處理進行中。",
"content": {
"key": "54886f30612771f8f10d94499a41a347",
"prc": "247",
"cardno": "493817******0003",
"acode": "063218",
"card_type": "1",
"issuing_bank": "合作金庫",
"issuing_bank_uid": "006",
"transaction_mode": 1,
"supplier_name": "凱基銀行",
"supplier_code": "BC",
"order_id": "1234567890",
"user_id": "phper",
"uid": 103283,
"cost": 10,
"currency": "TWD",
"actual_cost": 0,
"actual_currency": "TWD",
"voucher_paid": [],
"voucher_free": [],
"price": 0,
"actual_price": 0,
"recharge_code": "",
"love_cost": 0,
"retmsg": "請款進行中",
"pay_mode_uid": 1,
"pfn": "CREDITCARD",
"trans_type": 1,
"redeem": "",
"installment": "",
"finishtime": "",
"store_group_id": "",
"group_id": "",
"nois": "",
"payment_name": "",
"bank_id": "",
"result_type": 4,
"result_content_type": "CREDITCARD",
"result_content": "{}",
"expired_date": "",
"appropriation_date": "",
"invoice_state": 0,
"invoice_date": "20220301160234",
"invoice_wordtrack": "JH",
"invoice_number": "00000014",
"invoice_rand_code": "4224",
"invoice_seller_ban": "28915188",
"invoice_buyer_ban": "",
"invoice_left_qrcode": "JH00000014111030142240000000a0000000a0000000028915188DdkbPtMzNyH4rp0qk7dRig==:**********:1:1:1:商品名稱:1:10:",
"invoice_middle_barcode": "11104JH000000144224",
"invoice_right_qrcode": "**",
"invoice_title_type": 1,
"invoice_title": "123",
"invoice_print_type": 0,
"invoice_print_device": 0,
"invoice_amount": "10",
"invoice_sales_amount": "10",
"invoice_tax_amount": "0",
"invoice_order_detail": "[{\"Description\":\"商品名稱\",\"Quantity\":\"1\",\"UnitPrice\":\"10\",\"Amount\":\"10\"}]",
"invoice_ratetype": 1,
"invoice_input_type": 1,
"invoice_cloud_type": 2,
"invoice_mobile_code": "\/NFVIAZP",
"invoice_tax_id": "",
"invoice_natural_person": "",
"invoice_love_code": "",
"invoice_b2b_title": "",
"invoice_b2b_id": "",
"invoice_b2b_post_zone": "",
"invoice_b2b_address": "",
"invoice_allowance": [],
"refund_order": [],
"cancel_order": [],
"echo_0": "",
"echo_1": "",
"echo_2": "",
"echo_3": "",
"echo_4": ""
}
} 信用卡類交易,若使用自行請款模式,交易狀態為授權完成(245)時,則可以發動此信用卡授權請款,用以完成交易。發動只限定一次。可全額或部分請款。
授權請款天數限制
1.請款有天數限制,依照銀行跟代收及非代收的情況,而有所不同,一旦超過請款天數限制,則無法請款,只能重新交易
2.代收付特約商店:一律5天內須要發動請款。
3.非代收付特約商店:依據不同銀行,天數不同,請參考下表,如不再此表內的銀行,代表未支援
| 銀行名稱 | 天數 |
|---|---|
| 凱基銀行 | 5天 |
| 台新銀行 | 5天 |
| 國泰銀行 | 5天 |
經銷商『信用卡授權請款』參數說明
| 欄位 | 型態 | 說明 |
|---|---|---|
| agent_uid | string(16) | 經銷商商務代號 |
| service | text | {"service_name": "api", "cmd": "api\/authorizedrequestpayment"}JSON格式,AES256加密資料 |
| encry_data | text | 『信用卡授權請款』欄位參考 JSON格式,AES256加密資料 |
『信用卡授權請款』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| store_uid | string | 特約商店編號 | 必填 |
| uid | string | 交易流水號 | |
| key | string | 交易驗証碼 | |
| cost | integer | 總請款金額 | |
| items | array | 請款的產品項目(商品名稱必須與原交易時商品名稱相同) 需帶入完整的實際請款產品項目 | 每筆『商品項目』欄位參考 |
『信用卡授權請款』回傳欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| code | string | 交易回傳碼 | |
| msg | string | 回傳訊息 | |
| content | object | 查詢內容 | 『交易查詢』欄位參考 |
定期定額式扣款取消
當消費者希望取消定期扣款,用此方法發動取消繼續扣款。
<?php
/**
* 經銷商串接-取消定期定額訂單
*/
final class AgentDirectDebitDisabled
{
/**
* 經銷商商務代號
* @var string
*/
public $agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
* @var string
*/
public $agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號(代特約商店發動)
* @var string
*/
public $storeUid = "289151880002";
/**
* 串接交易位置
* @var string
*/
public $url = "https://ka.usecase.cc/api/agent";
/**
* 取得串接欄位資料
* @return array
*/
public function getRawData()
{
$rawData = array();
$rawData['store_uid'] = $this->storeUid;
$rawData['order_id'] = "F3DCB0AD-23F3-4721-BBBA-FAC8CDDB9E5F";
$rawData['group_id'] = "D0000000520";
$rawData['stop_time'] = "20180920";
$rawData['stop_reason'] = "消費者不喜翻~";
return $rawData;
}
/**
* 取得服務位置
* @return array
*/
public function getService()
{
return array(
'service_name' => 'api',
'cmd' => 'api/disabledirectdebit'
);
}
/**
* AES 256 加密
* @param array $fields
* @param string $key
* @return string
*/
public 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;
}
/**
* 資料 POST 到主機
* @param array $postData
* @return mixed
*/
public function post($postData = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* 取得送出欄位資料
* @return array
*/
public function getPostData ()
{
$postData = array();
$postData['agent_uid'] = $this->agentUid;
$postData['service'] = $this->encrypt($this->getService(), $this->agentKey);
$postData['encry_data'] = $this->encrypt($this->getRawData(), $this->agentKey);
return $postData;
}
/**
* 執行
*/
public function run()
{
$json = $this->post($this->getPostData());
echo $json;
}
}
$AgentDirectDebitDisabled = new AgentDirectDebitDisabled();
$AgentDirectDebitDisabled->run();
?>
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Dynamic;
/// <summary>
/// 建議使用.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也可能無法使用
/// </summary>
namespace MyPay {
/// <summary>
/// 經銷商串接-取消定期定額訂單
/// </summary>
public class AgentDirectDebitDisabled {
/// <summary>
/// 經銷商商務代號
/// </summary>
public string agentUid = "518169081001";
/// <summary>
/// 經銷商金鑰或認證碼
/// </summary>
public string agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/// <summary>
/// 特約商店商務代號
/// </summary>
public string storeUid = "289151880002";
/// <summary>
/// 串接交易位置
/// </summary>
public string url = "https://ka.usecase.cc/api/agent";
/// <summary>
/// 執行
/// </summary>
static void Main() {
AgentDirectDebitDisabled simulator = new AgentDirectDebitDisabled();
//僅限走https的Tls 1.2以上版本
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//發送至遠端
var result = simulator.Post(simulator.GetPostData());
System.Console.WriteLine(result);
}
/// <summary>
/// 取得串接欄位資料
/// </summary>
private dynamic GetRawData() {
dynamic rawData = new ExpandoObject();
rawData.store_uid = this.storeUid;
rawData.order_id = "F3DCB0AD-23F3-4721-BBBA-FAC8CDDB9E5F";
rawData.group_id = "D0000000520";
rawData.stop_time = "20180920";
rawData.stop_reason = "消費者不喜翻~";
return rawData;
}
/// <summary>
/// 取得服務位置
/// </summary>
private ServiceRequest GetService() {
ServiceRequest rawData = new ServiceRequest();
rawData.service_name = "api";
rawData.cmd = "api/disabledirectdebit";
return rawData;
}
/// <summary>
/// 取得送出欄位資料
/// </summary>
private NameValueCollection GetPostData() {
string data_json = JsonConvert.SerializeObject(GetRawData(), Formatting.None);
string svr_json = JsonConvert.SerializeObject(GetService(), Formatting.None);; //依API種類調整
//產生AES向量
var IV = GetBytesIV();
//進行加密
var data_encode = Encrypt(data_json, this.agentKey, IV);
var svr_encode = Encrypt(svr_json, this.agentKey, IV);
//請注意使用的 Http Post 套件是否會自動加上UrlEncode,本Post範例為原始方式,故須加上UrlEncode
//若自行使用的套件會自動補上UrlEncode,則請忽略下面的UrlEncode,避免做了兩次UrlEncode
string data_toUrlEncode = HttpUtility.UrlEncode(data_encode);
string svr_toUrlEncode = HttpUtility.UrlEncode(svr_encode);
NameValueCollection postData = new NameValueCollection();
postData["agent_uid"] = this.agentUid;
postData["service"] = svr_toUrlEncode;
postData["encry_data"] = data_toUrlEncode;
return postData;
}
/// <summary>
/// AES 256 加密
/// </summary>
/// <param name="data"></param>
/// <param name="key"></param>
/// <param name="byteIV"></param>
/// <returns></returns>
private string Encrypt(string data, string key, byte[] byteIV) {
var byteKey = System.Text.Encoding.UTF8.GetBytes(key);
var enBytes = AES_Encrypt(data, byteKey, byteIV);
return Convert.ToBase64String(BytesAdd(byteIV, enBytes));
}
/// <summary>
/// AES 256 加密處理
/// </summary>
/// <param name="original"></param>
/// <param name="key"></param>
/// <param name="iv"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 轉換Bytes
/// </summary>
/// <param name="a"></param>
/// <param name="arryB"></param>
/// <returns></returns>
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();
}
/// <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;
}
/// <summary>
/// 資料 POST 到主機
/// </summary>
/// <param name="pars"></param>
/// <returns></returns>
private string Post(NameValueCollection pars) {
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(this.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>
/// 串接服務請求欄位
/// </summary>
public class ServiceRequest {
public string service_name { get; set; }
public string cmd { get; set; }
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URLEncoder;
import java.util.*;
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 static java.nio.charset.StandardCharsets.UTF_8;
import org.spongycastle.crypto.engines.AESEngine;
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 java.security.SecureRandom;
/**
* 經銷商串接-取消定期定額訂單
* 1. jackson-core 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
* 2. jackson-databind 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
* 3. jackson-annotations 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
* 4. Spongy Castle 下載 https://mvnrepository.com/artifact/com.madgag.spongycastle/core
*/
public class AgentDirectDebitDisabled {
/**
* 經銷商商務代號
*/
String agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
*/
String agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號
*/
String storeUid = "289151880002";
/**
* 串接交易位置
*/
String url = "https://ka.usecase.cc/api/agent";
/**
* 執行
* @param args
*/
public static void main(String[] args) {
AgentDirectDebitDisabled simulator = new AgentDirectDebitDisabled();
String json = simulator.post(simulator.getPostData());
System.out.print(json);
}
@SuppressWarnings(value = { "unchecked", "deprecation" })
/**
* 取得串接欄位資料
* @return 串接原始資料
*/
public Map getRawData() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("store_uid", this.storeUid);
rawData.put("order_id", "F3DCB0AD-23F3-4721-BBBA-FAC8CDDB9E5F");
rawData.put("group_id", "D0000000520");
rawData.put("stop_time", "20180920");
rawData.put("stop_reason", "消費者不喜翻~");
return rawData;
}
/**
* 取得服務位置
* @return 串接服務資料
*/
public Map getService() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("service_name", "api");
rawData.put("cmd", "api/disabledirectdebit");
return rawData;
}
/**
* AES 256 加密
* @param rawData 原始資料
* @param AesKey AES256金鑰字串
* @return 轉換成Base64資料
*/
public String encrypt(Map rawData, String AesKey) {
try {
ObjectMapper objMapper = new ObjectMapper();
byte[] data = objMapper.writeValueAsString(rawData).getBytes(UTF_8);
byte[] key = AesKey.getBytes(UTF_8);
// 16 bytes is the IV size for AES256
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
// 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);
Base64.Encoder encoder = Base64.getEncoder();
String base64 = encoder.encodeToString(outBuf2);
return base64;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
/**
* 資料 POST 到主機
* @param qstr 串接資料
* @return 服務回傳JSON資訊
*/
public String post(String qstr) {
String result = "";
try {
// 資料
byte[] qstr_bytes = qstr.getBytes(StandardCharsets.UTF_8);
URL iurl = new URL(this.url);
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 + "\r\n");
}
try {
result = response.toString();
} finally {
in.close();
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return result;
}
/**
* 取得送出欄位資料
* @return POST完整資料
*/
public String getPostData() {
String postData = "";
try {
// Base64需要使用UrlEncode做傳輸
String data_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getRawData(), this.agentKey), "UTF-8");
String svr_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getService(), this.agentKey), "UTF-8");
postData = "agent_uid=" + this.agentUid + "&service="
+ svr_toUrlEncode + "&encry_data=" + data_toUrlEncode;
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return postData;
}
}
const crypto = require('crypto');
const httpRequest = require('https');
/**
* 經銷商串接-取消定期定額訂單
*/
function AgentDirectDebitDisabled() {
// 經銷商商務代號
this.agentUid = "518169081001";
// 經銷商金鑰或認證碼
this.agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
// 特約商店商務代號
this.storeUid = "289151880002";
// 串接交易位置
this.url = "https://ka.usecase.cc/api/agent";
};
/**
* 取得串接欄位資料
*/
AgentDirectDebitDisabled.prototype.getRawData = function () {
return {
store_uid: this.storeUid,
order_id: "F3DCB0AD-23F3-4721-BBBA-FAC8CDDB9E5F",
group_id: "D0000000520",
stop_time: "20180920",
stop_reason: "消費者不喜翻~",
};
};
/**
* 取得服務位置
*/
AgentDirectDebitDisabled.prototype.getService = function () {
return {
service_name: "api",
cmd: "api/disabledirectdebit"
};
};
/**
* AES 256 加密
*/
AgentDirectDebitDisabled.prototype.encrypt = function (fields, key) {
let eData = JSON.stringify(fields);
const blockSize = 16;
const iv = crypto.randomBytes(blockSize);
const encryptor = crypto.createCipheriv('aes-256-cbc', key, iv);
let tmpCipher = encryptor.update(Buffer.from(eData));
let finalCipher = encryptor.final();
const tempData = Buffer.concat([tmpCipher, finalCipher], tmpCipher.length + finalCipher.length);
let data = Buffer.concat([iv, tempData], iv.length + tempData.length).toString('base64');
return data;
};
/**
* 資料 POST 到主機
*/
AgentDirectDebitDisabled.prototype.post = function (postData) {
return new Promise((res, rej) => {
let options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
rejectUnauthorized: false
};
let send_process = httpRequest.request(this.url, options, (api_res) => {
let res_data = "";
api_res.on('data', (tmp_data) => {
res_data += tmp_data;
});
api_res.on('end', () => {
res(res_data);
});
});
send_process.write(JSON.stringify(postData));
send_process.end();
});
};
/**
* 取得送出欄位資料
*/
AgentDirectDebitDisabled.prototype.getPostData = function () {
return {
"agent_uid": this.agentUid,
"service": this.encrypt(this.getService(), this.agentKey),
"encry_data": this.encrypt(this.getRawData(), this.agentKey)
};
};
/**
* 執行
*/
AgentDirectDebitDisabled.prototype.run = async function () {
json = await this.post(this.getPostData())
console.log(json);
};
AgentDirectDebitDisabled = new AgentDirectDebitDisabled();
AgentDirectDebitDisabled.run();
# -*- coding: utf-8 -*-
import json
import base64
import requests
from Crypto.Cipher import AES
from Crypto.Util import Padding
from Crypto.Random import get_random_bytes
"""經銷商串接-取消定期定額訂單
"""
class AgentDirectDebitDisabled:
# 經銷商商務代號
agentUid = "518169081001";
# 經銷商金鑰或認證碼
agentKey = b"0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
# 特約商店商務代號
storeUid = "289151880002"
# 串接交易位置
url = "https://ka.usecase.cc/api/agent"
def getRawData(self):
"""取得串接欄位資料
Returns:
{dict}: 欄位資料
"""
rawData = {
'store_uid': self.storeUid,
'order_id': "F3DCB0AD-23F3-4721-BBBA-FAC8CDDB9E5F",
'group_id': "D0000000520",
'stop_time': "20180920",
'stop_reason': "消費者不喜翻~",
}
return rawData
def getService(self):
"""取得服務位置
Returns:
{dict}: 服務位置資料
"""
return {
'service_name': 'api',
'cmd': 'api/disabledirectdebit'
}
def encrypt(self, fields, key):
"""AES 256 加密
Args:
fields {dict}: 欄位資料
key {bytes}: AES金鑰
Returns:
{string}: 加密資料
"""
data = json.dumps(fields, separators=(',', ':'))
data = Padding.pad(data.encode('utf-8'), AES.block_size)
iv = get_random_bytes(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
data = cipher.encrypt(data)
data = base64.b64encode(iv + data)
return data
def post(self, postData):
"""資料 POST 到主機
Args:
postData {dict}: 欄位資料
Returns:
{string}: JSON資料
"""
result = requests.post(self.url, postData)
return result.text
def getPostData(self):
"""取得送出欄位資料
Returns:
{dict}: 欄位資料
"""
postData = {
'agent_uid': self.agentUid,
'service': self.encrypt(self.getService(), self.agentKey),
'encry_data': self.encrypt(self.getRawData(), self.agentKey)
}
return postData
def run(self):
"""執行
"""
json = self.post(self.getPostData())
print(json)
AgentDirectDebitDisabled = AgentDirectDebitDisabled()
AgentDirectDebitDisabled.run()
回傳 JSON 結構如下:
{
"code": "B500",
"msg": "停扣日必須大於今日",
"order_id": "F3DCB0AD-23F3-4721-BBBA-FAC8CDDB9E5F",
"group_id": "D0000000520"
}經銷商『定期定額式扣款取消』參數說明
| 欄位 | 型態 | 說明 |
|---|---|---|
| agent_uid | string(16) | 經銷商商務代號 |
| service | text | {"service_name": "api", "cmd": "api\/disabledirectdebit"}JSON格式,AES256加密資料 |
| encry_data | text | 『定期定額式扣款取消』欄位參考 JSON格式,AES256加密資料 |
『定期定額式扣款取消』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| store_uid | string | 特約商店商務代號 | |
| order_id | string | 定期扣款之訂單編號 | |
| group_id | string | 定期扣款群組編號 | |
| stop_time | string | 取消日期 (時間格是為YYYYMMDD) | |
| stop_reason | string | 取消原因 |
『定期定額式扣款取消』回傳欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| code | string | 回傳碼 | |
| msg | string | 訊息說明 | |
| order_id | string | 定期扣款之訂單編號 | |
| group_id | string | 定期扣款群組編號 |
MYPAY電子錢包綁定
特店產生一組token專屬會員,以後會員後續交易時,不需要再輸入卡號,加速交易流程與資訊安全。 發動API呼叫信用卡綁定頁面,消費者將信用卡號輸入,系統會綁定貴司電子錢包時,當完成時將畫面導回貴司網站,並會背景通報結果。
<?php
/**
* 經銷商串接-MYPAY電子錢包綁定
*/
final class AgentEWalletBind
{
/**
* 經銷商商務代號
* @var string
*/
public $agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
* @var string
*/
public $agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號(代特約商店發動)
* @var string
*/
public $storeUid = "289151880002";
/**
* 串接交易位置
* @var string
*/
public $url = "https://ka.usecase.cc/api/agent";
/**
* 取得串接欄位資料
* @return array
*/
public function getRawData()
{
$rawData = array();
$rawData['store_uid'] = $this->storeUid;
$rawData['user_id'] = "phper";
$rawData['user_sn'] = "A123456789";
$rawData['user_cellphone_code'] = "886";
$rawData['user_cellphone'] = "918123123";
$rawData['user_real_name'] = "金城武";
$rawData['user_email'] = "該 Email 地址已受到反垃圾郵件外掛保護。要顯示它需要在瀏覽器中啓用 JavaScript。 ";
$rawData['user_english_name'] = "Takeshi Kaneshiro";
$rawData['user_address'] = "台中市西區台灣大道二段573號6樓E室";
$rawData['pfn'] = "CREDITCARD";
$rawData['ip'] = "127.0.0.1";
$rawData['success_returl'] = "https://www.mypay.com.tw/";
$rawData['failure_returl'] = "https://www.google.com.tw/";
return $rawData;
}
/**
* 取得服務位置
* @return array
*/
public function getService()
{
return array(
'service_name' => 'api',
'cmd' => 'api/ewalletbind'
);
}
/**
* AES 256 加密
* @param array $fields
* @param string $key
* @return string
*/
public 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;
}
/**
* 資料 POST 到主機
* @param array $postData
* @return mixed
*/
public function post($postData = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* 取得送出欄位資料
* @return array
*/
public function getPostData ()
{
$postData = array();
$postData['agent_uid'] = $this->agentUid;
$postData['service'] = $this->encrypt($this->getService(), $this->agentKey);
$postData['encry_data'] = $this->encrypt($this->getRawData(), $this->agentKey);
return $postData;
}
/**
* 執行
*/
public function run()
{
$json = $this->post($this->getPostData());
echo $json;
}
}
$AgentEWalletBind = new AgentEWalletBind();
$AgentEWalletBind->run();
?>
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Dynamic;
/// <summary>
/// 建議使用.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也可能無法使用
/// </summary>
namespace MyPay {
/// <summary>
/// 經銷商串接-MYPAY電子錢包綁定
/// </summary>
public class AgentEWalletBind {
/// <summary>
/// 經銷商商務代號
/// </summary>
public string agentUid = "518169081001";
/// <summary>
/// 經銷商金鑰或認證碼
/// </summary>
public string agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/// <summary>
/// 特約商店商務代號
/// </summary>
public string storeUid = "289151880002";
/// <summary>
/// 串接交易位置
/// </summary>
public string url = "https://ka.usecase.cc/api/agent";
/// <summary>
/// 執行
/// </summary>
static void Main() {
AgentEWalletBind simulator = new AgentEWalletBind();
//僅限走https的Tls 1.2以上版本
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//發送至遠端
var result = simulator.Post(simulator.GetPostData());
System.Console.WriteLine(result);
}
/// <summary>
/// 取得串接欄位資料
/// </summary>
private dynamic GetRawData() {
dynamic rawData = new ExpandoObject();
rawData.store_uid = this.storeUid;
rawData.user_id = "phper";
rawData.user_sn = "A123456789";
rawData.user_cellphone_code = "886";
rawData.user_cellphone = "918123123";
rawData.user_real_name = "金城武";
rawData.user_email = "該 Email 地址已受到反垃圾郵件外掛保護。要顯示它需要在瀏覽器中啓用 JavaScript。 ";
rawData.user_english_name = "Takeshi Kaneshiro";
rawData.user_address = "台中市西區台灣大道二段573號6樓E室";
rawData.pfn = "CREDITCARD";
rawData.ip = "127.0.0.1";
rawData.success_returl = "https://www.mypay.com.tw/";
rawData.failure_returl = "https://www.google.com.tw/";
return rawData;
}
/// <summary>
/// 取得服務位置
/// </summary>
private ServiceRequest GetService() {
ServiceRequest rawData = new ServiceRequest();
rawData.service_name = "api";
rawData.cmd = "api/ewalletbind";
return rawData;
}
/// <summary>
/// 取得送出欄位資料
/// </summary>
private NameValueCollection GetPostData() {
string data_json = JsonConvert.SerializeObject(GetRawData(), Formatting.None);
string svr_json = JsonConvert.SerializeObject(GetService(), Formatting.None);; //依API種類調整
//產生AES向量
var IV = GetBytesIV();
//進行加密
var data_encode = Encrypt(data_json, this.agentKey, IV);
var svr_encode = Encrypt(svr_json, this.agentKey, IV);
//請注意使用的 Http Post 套件是否會自動加上UrlEncode,本Post範例為原始方式,故須加上UrlEncode
//若自行使用的套件會自動補上UrlEncode,則請忽略下面的UrlEncode,避免做了兩次UrlEncode
string data_toUrlEncode = HttpUtility.UrlEncode(data_encode);
string svr_toUrlEncode = HttpUtility.UrlEncode(svr_encode);
NameValueCollection postData = new NameValueCollection();
postData["agent_uid"] = this.agentUid;
postData["service"] = svr_toUrlEncode;
postData["encry_data"] = data_toUrlEncode;
return postData;
}
/// <summary>
/// AES 256 加密
/// </summary>
/// <param name="data"></param>
/// <param name="key"></param>
/// <param name="byteIV"></param>
/// <returns></returns>
private string Encrypt(string data, string key, byte[] byteIV) {
var byteKey = System.Text.Encoding.UTF8.GetBytes(key);
var enBytes = AES_Encrypt(data, byteKey, byteIV);
return Convert.ToBase64String(BytesAdd(byteIV, enBytes));
}
/// <summary>
/// AES 256 加密處理
/// </summary>
/// <param name="original"></param>
/// <param name="key"></param>
/// <param name="iv"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 轉換Bytes
/// </summary>
/// <param name="a"></param>
/// <param name="arryB"></param>
/// <returns></returns>
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();
}
/// <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;
}
/// <summary>
/// 資料 POST 到主機
/// </summary>
/// <param name="pars"></param>
/// <returns></returns>
private string Post(NameValueCollection pars) {
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(this.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>
/// 串接服務請求欄位
/// </summary>
public class ServiceRequest {
public string service_name { get; set; }
public string cmd { get; set; }
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URLEncoder;
import java.util.*;
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 static java.nio.charset.StandardCharsets.UTF_8;
import org.spongycastle.crypto.engines.AESEngine;
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 java.security.SecureRandom;
/**
* 經銷商串接-MYPAY電子錢包綁定
* 1. jackson-core 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
* 2. jackson-databind 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
* 3. jackson-annotations 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
* 4. Spongy Castle 下載 https://mvnrepository.com/artifact/com.madgag.spongycastle/core
*/
public class AgentEWalletBind {
/**
* 經銷商商務代號
*/
String agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
*/
String agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號
*/
String storeUid = "289151880002";
/**
* 串接交易位置
*/
String url = "https://ka.usecase.cc/api/agent";
/**
* 執行
* @param args
*/
public static void main(String[] args) {
AgentEWalletBind simulator = new AgentEWalletBind();
String json = simulator.post(simulator.getPostData());
System.out.print(json);
}
@SuppressWarnings(value = { "unchecked", "deprecation" })
/**
* 取得串接欄位資料
* @return 串接原始資料
*/
public Map getRawData() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("store_uid", this.storeUid);
rawData.put("user_id", "phper");
rawData.put("user_sn", "A123456789");
rawData.put("user_cellphone_code", "886");
rawData.put("user_cellphone", "918123123");
rawData.put("user_real_name", "金城武");
rawData.put("user_email", "該 Email 地址已受到反垃圾郵件外掛保護。要顯示它需要在瀏覽器中啓用 JavaScript。 ");
rawData.put("user_english_name", "Takeshi Kaneshiro");
rawData.put("user_address", "台中市西區台灣大道二段573號6樓E室");
rawData.put("pfn", "CREDITCARD");
rawData.put("ip", "127.0.0.1");
rawData.put("success_returl", "https://www.mypay.com.tw/");
rawData.put("failure_returl", "https://www.google.com.tw/");
return rawData;
}
/**
* 取得服務位置
* @return 串接服務資料
*/
public Map getService() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("service_name", "api");
rawData.put("cmd", "api/ewalletbind");
return rawData;
}
/**
* AES 256 加密
* @param rawData 原始資料
* @param AesKey AES256金鑰字串
* @return 轉換成Base64資料
*/
public String encrypt(Map rawData, String AesKey) {
try {
ObjectMapper objMapper = new ObjectMapper();
byte[] data = objMapper.writeValueAsString(rawData).getBytes(UTF_8);
byte[] key = AesKey.getBytes(UTF_8);
// 16 bytes is the IV size for AES256
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
// 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);
Base64.Encoder encoder = Base64.getEncoder();
String base64 = encoder.encodeToString(outBuf2);
return base64;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
/**
* 資料 POST 到主機
* @param qstr 串接資料
* @return 服務回傳JSON資訊
*/
public String post(String qstr) {
String result = "";
try {
// 資料
byte[] qstr_bytes = qstr.getBytes(StandardCharsets.UTF_8);
URL iurl = new URL(this.url);
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 + "\r\n");
}
try {
result = response.toString();
} finally {
in.close();
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return result;
}
/**
* 取得送出欄位資料
* @return POST完整資料
*/
public String getPostData() {
String postData = "";
try {
// Base64需要使用UrlEncode做傳輸
String data_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getRawData(), this.agentKey), "UTF-8");
String svr_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getService(), this.agentKey), "UTF-8");
postData = "agent_uid=" + this.agentUid + "&service="
+ svr_toUrlEncode + "&encry_data=" + data_toUrlEncode;
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return postData;
}
}
const crypto = require('crypto');
const httpRequest = require('https');
/**
* 經銷商串接-取消定期定額訂單
*/
function AgentDirectDebitDisabled() {
// 經銷商商務代號
this.agentUid = "518169081001";
// 經銷商金鑰或認證碼
this.agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
// 特約商店商務代號
this.storeUid = "289151880002";
// 串接交易位置
this.url = "https://ka.usecase.cc/api/agent";
};
/**
* 取得串接欄位資料
*/
AgentDirectDebitDisabled.prototype.getRawData = function () {
return {
store_uid: this.storeUid,
order_id: "F3DCB0AD-23F3-4721-BBBA-FAC8CDDB9E5F",
group_id: "D0000000520",
stop_time: "20180920",
stop_reason: "消費者不喜翻~",
};
};
/**
* 取得服務位置
*/
AgentDirectDebitDisabled.prototype.getService = function () {
return {
service_name: "api",
cmd: "api/disabledirectdebit"
};
};
/**
* AES 256 加密
*/
AgentDirectDebitDisabled.prototype.encrypt = function (fields, key) {
let eData = JSON.stringify(fields);
const blockSize = 16;
const iv = crypto.randomBytes(blockSize);
const encryptor = crypto.createCipheriv('aes-256-cbc', key, iv);
let tmpCipher = encryptor.update(Buffer.from(eData));
let finalCipher = encryptor.final();
const tempData = Buffer.concat([tmpCipher, finalCipher], tmpCipher.length + finalCipher.length);
let data = Buffer.concat([iv, tempData], iv.length + tempData.length).toString('base64');
return data;
};
/**
* 資料 POST 到主機
*/
AgentDirectDebitDisabled.prototype.post = function (postData) {
return new Promise((res, rej) => {
let options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
rejectUnauthorized: false
};
let send_process = httpRequest.request(this.url, options, (api_res) => {
let res_data = "";
api_res.on('data', (tmp_data) => {
res_data += tmp_data;
});
api_res.on('end', () => {
res(res_data);
});
});
send_process.write(JSON.stringify(postData));
send_process.end();
});
};
/**
* 取得送出欄位資料
*/
AgentDirectDebitDisabled.prototype.getPostData = function () {
return {
"agent_uid": this.agentUid,
"service": this.encrypt(this.getService(), this.agentKey),
"encry_data": this.encrypt(this.getRawData(), this.agentKey)
};
};
/**
* 執行
*/
AgentDirectDebitDisabled.prototype.run = async function () {
json = await this.post(this.getPostData())
console.log(json);
};
AgentDirectDebitDisabled = new AgentDirectDebitDisabled();
AgentDirectDebitDisabled.run();
# -*- coding: utf-8 -*-
import json
import base64
import requests
from Crypto.Cipher import AES
from Crypto.Util import Padding
from Crypto.Random import get_random_bytes
"""經銷商串接-取消定期定額訂單
"""
class AgentDirectDebitDisabled:
# 經銷商商務代號
agentUid = "518169081001";
# 經銷商金鑰或認證碼
agentKey = b"0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
# 特約商店商務代號
storeUid = "289151880002"
# 串接交易位置
url = "https://ka.usecase.cc/api/agent"
def getRawData(self):
"""取得串接欄位資料
Returns:
{dict}: 欄位資料
"""
rawData = {
'store_uid': self.storeUid,
'order_id': "F3DCB0AD-23F3-4721-BBBA-FAC8CDDB9E5F",
'group_id': "D0000000520",
'stop_time': "20180920",
'stop_reason': "消費者不喜翻~",
}
return rawData
def getService(self):
"""取得服務位置
Returns:
{dict}: 服務位置資料
"""
return {
'service_name': 'api',
'cmd': 'api/disabledirectdebit'
}
def encrypt(self, fields, key):
"""AES 256 加密
Args:
fields {dict}: 欄位資料
key {bytes}: AES金鑰
Returns:
{string}: 加密資料
"""
data = json.dumps(fields, separators=(',', ':'))
data = Padding.pad(data.encode('utf-8'), AES.block_size)
iv = get_random_bytes(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
data = cipher.encrypt(data)
data = base64.b64encode(iv + data)
return data
def post(self, postData):
"""資料 POST 到主機
Args:
postData {dict}: 欄位資料
Returns:
{string}: JSON資料
"""
result = requests.post(self.url, postData)
return result.text
def getPostData(self):
"""取得送出欄位資料
Returns:
{dict}: 欄位資料
"""
postData = {
'agent_uid': self.agentUid,
'service': self.encrypt(self.getService(), self.agentKey),
'encry_data': self.encrypt(self.getRawData(), self.agentKey)
}
return postData
def run(self):
"""執行
"""
json = self.post(self.getPostData())
print(json)
AgentDirectDebitDisabled = AgentDirectDebitDisabled()
AgentDirectDebitDisabled.run()
回傳 JSON 結構如下:
{
"code": "B200",
"msg": "執行成功",
"url": "https:\/\/ka.usecase.cc\/ewallet\/107176.html"
}經銷商『MYPAY電子錢包綁定』參數說明
| 欄位 | 型態 | 說明 |
|---|---|---|
| agent_uid | string(16) | 經銷商商務代號 |
| service | text | {"service_name": "api", "cmd": "api\/ewalletbind"}JSON格式,AES256加密資料 |
| encry_data | text | 『MYPAY電子錢包綁定』欄位參考 JSON格式,AES256加密資料 |
『MYPAY電子錢包綁定』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| store_uid | string | 特約商店代碼 | 必填 |
| user_id | string | 消費者帳號 | 必填 |
| user_name | string | 消費者姓名 | |
| user_real_name | string | 消費者真實姓名 | |
| user_english_name | string | 消費者英文姓名 | |
| user_zipcode | string | 消費者郵遞區號 | |
| user_address | string | 消費者帳單地址 | |
| user_sn_type | string | 證號類型 | 『證號類型』值參考 |
| user_sn | string | 付款人身分證/統一證號/護照號碼 | |
| user_phone | string | 消費者家用電話 | |
| user_cellphone_code | string | 消費者行動電話國碼 | |
| user_cellphone | string | 消費者行動電話 | |
| user_email | string | 消費者 E-Mail | |
| user_birthday | string | 消費者生日 | |
| ip | string | 消費者來源 IP | 必填 |
| pfn | string | 綁定支付方式 | 『付款方式』值參考 |
| echo_0 | string | 自訂回傳參數 1 | |
| echo_1 | string | 自訂回傳參數 2 | |
| echo_2 | string | 自訂回傳參數 3 | |
| echo_3 | string | 自訂回傳參數 4 | |
| echo_4 | string | 自訂回傳參數 5 | |
| success_returl | string | 綁定成功導頁網址 | |
| failure_returl | string | 綁定失敗導頁網址 |
『MYPAY電子錢包綁定』回傳欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| code | string | 交易回傳碼 | 『電子錢包執行狀態碼』值參考 |
| msg | string | 回傳訊息 | |
| url | string | 交易網址 |
『電子錢包虛擬卡號回傳資訊』回報欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| pfn | string | 支付類型 | |
| cardno | string | 綁定卡號 (僅顯示前六後四) | |
| user_id | string | 消費者帳號 | |
| cellphone_code | string | 用以取消綁定之手機國碼 | |
| cellphone | string | 用以取消綁定之手機號碼 | |
| virtual_pan | string | 虛擬卡號 | |
| enable | string | 是否啟用 0.關閉 1.啟用 |
取消退款
當天發動退款請求時,會在系統退款柱列等待退款(現金類退款)。系統退款時間為隔天凌晨零時才發動退款,故在尚未做退款作業前,可發動此API請求,來取消(5)退款請求(也可透過管理介面來取消)。
<?php
/**
* 經銷商串接-取消退款
*/
final class AgentRefundCancel
{
/**
* 經銷商商務代號
* @var string
*/
public $agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
* @var string
*/
public $agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號(代特約商店發動)
* @var string
*/
public $storeUid = "289151880002";
/**
* 串接交易位置
* @var string
*/
public $url = "https://ka.usecase.cc/api/agent";
/**
* 取得串接欄位資料
* @return array
*/
public function getRawData()
{
$rawData = array();
$rawData['store_uid'] = $this->storeUid;
$rawData['uid'] = "30587";
$rawData['key'] = "2b848830072c0db6273d5637ad4b8337";
return $rawData;
}
/**
* 取得服務位置
* @return array
*/
public function getService()
{
return array(
'service_name' => 'api',
'cmd' => 'api/refundcancel'
);
}
/**
* AES 256 加密
* @param array $fields
* @param string $key
* @return string
*/
public 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;
}
/**
* 資料 POST 到主機
* @param array $postData
* @return mixed
*/
public function post($postData = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* 取得送出欄位資料
* @return array
*/
public function getPostData ()
{
$postData = array();
$postData['agent_uid'] = $this->agentUid;
$postData['service'] = $this->encrypt($this->getService(), $this->agentKey);
$postData['encry_data'] = $this->encrypt($this->getRawData(), $this->agentKey);
return $postData;
}
/**
* 執行
*/
public function run()
{
$json = $this->post($this->getPostData());
echo $json;
}
}
$AgentRefundCancel = new AgentRefundCancel();
$AgentRefundCancel->run();
?>
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Dynamic;
/// <summary>
/// 建議使用.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也可能無法使用
/// </summary>
namespace MyPay {
/// <summary>
/// 經銷商串接-取消退款
/// </summary>
public class AgentRefundCancel {
/// <summary>
/// 經銷商商務代號
/// </summary>
public string agentUid = "518169081001";
/// <summary>
/// 經銷商金鑰或認證碼
/// </summary>
public string agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/// <summary>
/// 特約商店商務代號
/// </summary>
public string storeUid = "289151880002";
/// <summary>
/// 串接交易位置
/// </summary>
public string url = "https://ka.usecase.cc/api/agent";
/// <summary>
/// 執行
/// </summary>
static void Main() {
AgentRefundCancel simulator = new AgentRefundCancel();
//僅限走https的Tls 1.2以上版本
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//發送至遠端
var result = simulator.Post(simulator.GetPostData());
System.Console.WriteLine(result);
}
/// <summary>
/// 取得串接欄位資料
/// </summary>
private dynamic GetRawData() {
dynamic rawData = new ExpandoObject();
rawData.store_uid = this.storeUid;
rawData.uid = "30587";
rawData.key = "2b848830072c0db6273d5637ad4b8337";
return rawData;
}
/// <summary>
/// 取得服務位置
/// </summary>
private ServiceRequest GetService() {
ServiceRequest rawData = new ServiceRequest();
rawData.service_name = "api";
rawData.cmd = "api/refundcancel";
return rawData;
}
/// <summary>
/// 取得送出欄位資料
/// </summary>
private NameValueCollection GetPostData() {
string data_json = JsonConvert.SerializeObject(GetRawData(), Formatting.None);
string svr_json = JsonConvert.SerializeObject(GetService(), Formatting.None);; //依API種類調整
//產生AES向量
var IV = GetBytesIV();
//進行加密
var data_encode = Encrypt(data_json, this.agentKey, IV);
var svr_encode = Encrypt(svr_json, this.agentKey, IV);
//請注意使用的 Http Post 套件是否會自動加上UrlEncode,本Post範例為原始方式,故須加上UrlEncode
//若自行使用的套件會自動補上UrlEncode,則請忽略下面的UrlEncode,避免做了兩次UrlEncode
string data_toUrlEncode = HttpUtility.UrlEncode(data_encode);
string svr_toUrlEncode = HttpUtility.UrlEncode(svr_encode);
NameValueCollection postData = new NameValueCollection();
postData["agent_uid"] = this.agentUid;
postData["service"] = svr_toUrlEncode;
postData["encry_data"] = data_toUrlEncode;
return postData;
}
/// <summary>
/// AES 256 加密
/// </summary>
/// <param name="data"></param>
/// <param name="key"></param>
/// <param name="byteIV"></param>
/// <returns></returns>
private string Encrypt(string data, string key, byte[] byteIV) {
var byteKey = System.Text.Encoding.UTF8.GetBytes(key);
var enBytes = AES_Encrypt(data, byteKey, byteIV);
return Convert.ToBase64String(BytesAdd(byteIV, enBytes));
}
/// <summary>
/// AES 256 加密處理
/// </summary>
/// <param name="original"></param>
/// <param name="key"></param>
/// <param name="iv"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 轉換Bytes
/// </summary>
/// <param name="a"></param>
/// <param name="arryB"></param>
/// <returns></returns>
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();
}
/// <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;
}
/// <summary>
/// 資料 POST 到主機
/// </summary>
/// <param name="pars"></param>
/// <returns></returns>
private string Post(NameValueCollection pars) {
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(this.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>
/// 串接服務請求欄位
/// </summary>
public class ServiceRequest {
public string service_name { get; set; }
public string cmd { get; set; }
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URLEncoder;
import java.util.*;
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 static java.nio.charset.StandardCharsets.UTF_8;
import org.spongycastle.crypto.engines.AESEngine;
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 java.security.SecureRandom;
/**
* 經銷商串接-取消退款
* 1. jackson-core 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
* 2. jackson-databind 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
* 3. jackson-annotations 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
* 4. Spongy Castle 下載 https://mvnrepository.com/artifact/com.madgag.spongycastle/core
*/
public class AgentRefundCancel {
/**
* 經銷商商務代號
*/
String agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
*/
String agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號
*/
String storeUid = "289151880002";
/**
* 串接交易位置
*/
String url = "https://ka.usecase.cc/api/agent";
/**
* 執行
* @param args
*/
public static void main(String[] args) {
AgentRefundCancel simulator = new AgentRefundCancel();
String json = simulator.post(simulator.getPostData());
System.out.print(json);
}
@SuppressWarnings(value = { "unchecked", "deprecation" })
/**
* 取得串接欄位資料
* @return 串接原始資料
*/
public Map getRawData() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("store_uid", this.storeUid);
rawData.put("uid", "30587");
rawData.put("key", "2b848830072c0db6273d5637ad4b8337");
return rawData;
}
/**
* 取得服務位置
* @return 串接服務資料
*/
public Map getService() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("service_name", "api");
rawData.put("cmd", "api/refundcancel");
return rawData;
}
/**
* AES 256 加密
* @param rawData 原始資料
* @param AesKey AES256金鑰字串
* @return 轉換成Base64資料
*/
public String encrypt(Map rawData, String AesKey) {
try {
ObjectMapper objMapper = new ObjectMapper();
byte[] data = objMapper.writeValueAsString(rawData).getBytes(UTF_8);
byte[] key = AesKey.getBytes(UTF_8);
// 16 bytes is the IV size for AES256
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
// 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);
Base64.Encoder encoder = Base64.getEncoder();
String base64 = encoder.encodeToString(outBuf2);
return base64;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
/**
* 資料 POST 到主機
* @param qstr 串接資料
* @return 服務回傳JSON資訊
*/
public String post(String qstr) {
String result = "";
try {
// 資料
byte[] qstr_bytes = qstr.getBytes(StandardCharsets.UTF_8);
URL iurl = new URL(this.url);
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 + "\r\n");
}
try {
result = response.toString();
} finally {
in.close();
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return result;
}
/**
* 取得送出欄位資料
* @return POST完整資料
*/
public String getPostData() {
String postData = "";
try {
// Base64需要使用UrlEncode做傳輸
String data_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getRawData(), this.agentKey), "UTF-8");
String svr_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getService(), this.agentKey), "UTF-8");
postData = "agent_uid=" + this.agentUid + "&service="
+ svr_toUrlEncode + "&encry_data=" + data_toUrlEncode;
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return postData;
}
}
const crypto = require('crypto');
const httpRequest = require('https');
/**
* 經銷商串接-取消退款
*/
function AgentRefundCancel() {
// 經銷商商務代號
this.agentUid = "518169081001";
// 經銷商金鑰或認證碼
this.agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
// 特約商店商務代號
this.storeUid = "289151880002";
// 串接交易位置
this.url = "https://ka.usecase.cc/api/agent";
};
/**
* 取得串接欄位資料
*/
AgentRefundCancel.prototype.getRawData = function () {
return {
store_uid: this.storeUid,
uid: "30587",
key: "2b848830072c0db6273d5637ad4b8337",
};
};
/**
* 取得服務位置
*/
AgentRefundCancel.prototype.getService = function () {
return {
service_name: "api",
cmd: "api/refundcancel"
};
};
/**
* AES 256 加密
*/
AgentRefundCancel.prototype.encrypt = function (fields, key) {
let eData = JSON.stringify(fields);
const blockSize = 16;
const iv = crypto.randomBytes(blockSize);
const encryptor = crypto.createCipheriv('aes-256-cbc', key, iv);
let tmpCipher = encryptor.update(Buffer.from(eData));
let finalCipher = encryptor.final();
const tempData = Buffer.concat([tmpCipher, finalCipher], tmpCipher.length + finalCipher.length);
let data = Buffer.concat([iv, tempData], iv.length + tempData.length).toString('base64');
return data;
};
/**
* 資料 POST 到主機
*/
AgentRefundCancel.prototype.post = function (postData) {
return new Promise((res, rej) => {
let options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
rejectUnauthorized: false
};
let send_process = httpRequest.request(this.url, options, (api_res) => {
let res_data = "";
api_res.on('data', (tmp_data) => {
res_data += tmp_data;
});
api_res.on('end', () => {
res(res_data);
});
});
send_process.write(JSON.stringify(postData));
send_process.end();
});
};
/**
* 取得送出欄位資料
*/
AgentRefundCancel.prototype.getPostData = function () {
return {
"agent_uid": this.agentUid,
"service": this.encrypt(this.getService(), this.agentKey),
"encry_data": this.encrypt(this.getRawData(), this.agentKey)
};
};
/**
* 執行
*/
AgentRefundCancel.prototype.run = async function () {
json = await this.post(this.getPostData())
console.log(json);
};
AgentRefundCancel = new AgentRefundCancel();
AgentRefundCancel.run();
# -*- coding: utf-8 -*-
import json
import base64
import requests
from Crypto.Cipher import AES
from Crypto.Util import Padding
from Crypto.Random import get_random_bytes
"""經銷商串接-取消退款
"""
class AgentRefundCancel:
# 經銷商商務代號
agentUid = "518169081001";
# 經銷商金鑰或認證碼
agentKey = b"0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
# 特約商店商務代號
storeUid = "289151880002"
# 串接交易位置
url = "https://ka.usecase.cc/api/agent"
def getRawData(self):
"""取得串接欄位資料
Returns:
{dict}: 欄位資料
"""
rawData = {
'store_uid': self.storeUid,
'uid': "30587",
'key': "2b848830072c0db6273d5637ad4b8337",
}
return rawData
def getService(self):
"""取得服務位置
Returns:
{dict}: 服務位置資料
"""
return {
'service_name': 'api',
'cmd': 'api/refundcancel'
}
def encrypt(self, fields, key):
"""AES 256 加密
Args:
fields {dict}: 欄位資料
key {bytes}: AES金鑰
Returns:
{string}: 加密資料
"""
data = json.dumps(fields, separators=(',', ':'))
data = Padding.pad(data.encode('utf-8'), AES.block_size)
iv = get_random_bytes(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
data = cipher.encrypt(data)
data = base64.b64encode(iv + data)
return data
def post(self, postData):
"""資料 POST 到主機
Args:
postData {dict}: 欄位資料
Returns:
{string}: JSON資料
"""
result = requests.post(self.url, postData)
return result.text
def getPostData(self):
"""取得送出欄位資料
Returns:
{dict}: 欄位資料
"""
postData = {
'agent_uid': self.agentUid,
'service': self.encrypt(self.getService(), self.agentKey),
'encry_data': self.encrypt(self.getRawData(), self.agentKey)
}
return postData
def run(self):
"""執行
"""
json = self.post(self.getPostData())
print(json)
AgentRefundCancel = AgentRefundCancel()
AgentRefundCancel.run()
回傳 JSON 結構如下:
{
"key": "2b848830072c0db6273d5637ad4b8337",
"uid": "30587",
"code": "B500",
"msg": "無法取消此筆退款,原因為目前此筆狀態不是申請中。",
"row_data": null
}經銷商『取消退款』參數說明
| 欄位 | 型態 | 說明 |
|---|---|---|
| agent_uid | string(16) | 經銷商商務代號 |
| service | text | {"service_name": "api", "cmd": "api\/refundcancel"}JSON格式,AES256加密資料 |
| encry_data | text | 『取消退款』欄位參考 JSON格式,AES256加密資料 |
『取消退款』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| 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 | 退款資訊(即時退款才有此資訊) | 『退款完成回傳資訊』欄位參考 |
電子發票開立
發動交易時一起發動(請參閱PayPage金流交易 交易完成後獨立發動 本節說明獨立開立電子發票作法,交易完成後,可透過MYPAY再發動開立電子發票。電子發票必須在交易後當下立即發動開立,若因系統或服務當下無法開立發票,仍須在48小時內開立完畢。
<?php
/**
* 經銷商串接-開立發票
*/
final class AgentIssueInvoice
{
/**
* 經銷商商務代號
* @var string
*/
public $agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
* @var string
*/
public $agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號(代特約商店發動)
* @var string
*/
public $storeUid = "289151880002";
/**
* 串接交易位置
* @var string
*/
public $url = "https://ka.usecase.cc/api/agent";
/**
* 取得串接欄位資料
* @return array
*/
public function getRawData()
{
$rawData = array();
$rawData['store_uid'] = $this->storeUid;
$rawData['uid'] = "58793";
$rawData['key'] = "ab106dd223c66fd9258454c26e188f01";
$rawData['invoice_input_type'] = 1;
$rawData['invoice_cloud_type'] = 2;
$rawData['invoice_mobile_code'] = "/NFVIAZP";
return $rawData;
}
/**
* 取得服務位置
* @return array
*/
public function getService()
{
return array(
'service_name' => 'api',
'cmd' => 'api/issueinvoice'
);
}
/**
* AES 256 加密
* @param array $fields
* @param string $key
* @return string
*/
public 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;
}
/**
* 資料 POST 到主機
* @param array $postData
* @return mixed
*/
public function post($postData = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* 取得送出欄位資料
* @return array
*/
public function getPostData ()
{
$postData = array();
$postData['agent_uid'] = $this->agentUid;
$postData['service'] = $this->encrypt($this->getService(), $this->agentKey);
$postData['encry_data'] = $this->encrypt($this->getRawData(), $this->agentKey);
return $postData;
}
/**
* 執行
*/
public function run()
{
$json = $this->post($this->getPostData());
echo $json;
}
}
$AgentIssueInvoice = new AgentIssueInvoice();
$AgentIssueInvoice->run();
?>
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Dynamic;
/// <summary>
/// 建議使用.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也可能無法使用
/// </summary>
namespace MyPay {
/// <summary>
/// 經銷商串接-開立發票
/// </summary>
public class AgentIssueInvoice {
/// <summary>
/// 經銷商商務代號
/// </summary>
public string agentUid = "518169081001";
/// <summary>
/// 經銷商金鑰或認證碼
/// </summary>
public string agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/// <summary>
/// 特約商店商務代號
/// </summary>
public string storeUid = "289151880002";
/// <summary>
/// 串接交易位置
/// </summary>
public string url = "https://ka.usecase.cc/api/agent";
/// <summary>
/// 執行
/// </summary>
static void Main() {
AgentIssueInvoice simulator = new AgentIssueInvoice();
//僅限走https的Tls 1.2以上版本
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//發送至遠端
var result = simulator.Post(simulator.GetPostData());
System.Console.WriteLine(result);
}
/// <summary>
/// 取得串接欄位資料
/// </summary>
private dynamic GetRawData() {
dynamic rawData = new ExpandoObject();
rawData.store_uid = this.storeUid;
rawData.uid = "58793";
rawData.key = "ab106dd223c66fd9258454c26e188f01";
rawData.invoice_input_type = 1;
rawData.invoice_cloud_type = 2;
rawData.invoice_mobile_code = "/NFVIAZP";
return rawData;
}
/// <summary>
/// 取得服務位置
/// </summary>
private ServiceRequest GetService() {
ServiceRequest rawData = new ServiceRequest();
rawData.service_name = "api";
rawData.cmd = "api/issueinvoice";
return rawData;
}
/// <summary>
/// 取得送出欄位資料
/// </summary>
private NameValueCollection GetPostData() {
string data_json = JsonConvert.SerializeObject(GetRawData(), Formatting.None);
string svr_json = JsonConvert.SerializeObject(GetService(), Formatting.None);; //依API種類調整
//產生AES向量
var IV = GetBytesIV();
//進行加密
var data_encode = Encrypt(data_json, this.agentKey, IV);
var svr_encode = Encrypt(svr_json, this.agentKey, IV);
//請注意使用的 Http Post 套件是否會自動加上UrlEncode,本Post範例為原始方式,故須加上UrlEncode
//若自行使用的套件會自動補上UrlEncode,則請忽略下面的UrlEncode,避免做了兩次UrlEncode
string data_toUrlEncode = HttpUtility.UrlEncode(data_encode);
string svr_toUrlEncode = HttpUtility.UrlEncode(svr_encode);
NameValueCollection postData = new NameValueCollection();
postData["agent_uid"] = this.agentUid;
postData["service"] = svr_toUrlEncode;
postData["encry_data"] = data_toUrlEncode;
return postData;
}
/// <summary>
/// AES 256 加密
/// </summary>
/// <param name="data"></param>
/// <param name="key"></param>
/// <param name="byteIV"></param>
/// <returns></returns>
private string Encrypt(string data, string key, byte[] byteIV) {
var byteKey = System.Text.Encoding.UTF8.GetBytes(key);
var enBytes = AES_Encrypt(data, byteKey, byteIV);
return Convert.ToBase64String(BytesAdd(byteIV, enBytes));
}
/// <summary>
/// AES 256 加密處理
/// </summary>
/// <param name="original"></param>
/// <param name="key"></param>
/// <param name="iv"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 轉換Bytes
/// </summary>
/// <param name="a"></param>
/// <param name="arryB"></param>
/// <returns></returns>
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();
}
/// <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;
}
/// <summary>
/// 資料 POST 到主機
/// </summary>
/// <param name="pars"></param>
/// <returns></returns>
private string Post(NameValueCollection pars) {
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(this.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>
/// 串接服務請求欄位
/// </summary>
public class ServiceRequest {
public string service_name { get; set; }
public string cmd { get; set; }
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URLEncoder;
import java.util.*;
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 static java.nio.charset.StandardCharsets.UTF_8;
import org.spongycastle.crypto.engines.AESEngine;
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 java.security.SecureRandom;
/**
* 經銷商串接-開立發票
* 1. jackson-core 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
* 2. jackson-databind 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
* 3. jackson-annotations 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
* 4. Spongy Castle 下載 https://mvnrepository.com/artifact/com.madgag.spongycastle/core
*/
public class AgentIssueInvoice {
/**
* 經銷商商務代號
*/
String agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
*/
String agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號
*/
String storeUid = "289151880002";
/**
* 串接交易位置
*/
String url = "https://ka.usecase.cc/api/agent";
/**
* 執行
* @param args
*/
public static void main(String[] args) {
AgentIssueInvoice simulator = new AgentIssueInvoice();
String json = simulator.post(simulator.getPostData());
System.out.print(json);
}
@SuppressWarnings(value = { "unchecked", "deprecation" })
/**
* 取得串接欄位資料
* @return 串接原始資料
*/
public Map getRawData() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("store_uid", this.storeUid);
rawData.put("uid", "58793");
rawData.put("key", "ab106dd223c66fd9258454c26e188f01");
rawData.put("invoice_input_type", 1);
rawData.put("invoice_cloud_type", 2);
rawData.put("invoice_mobile_code", "/NFVIAZP");
return rawData;
}
/**
* 取得服務位置
* @return 串接服務資料
*/
public Map getService() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("service_name", "api");
rawData.put("cmd", "api/issueinvoice");
return rawData;
}
/**
* AES 256 加密
* @param rawData 原始資料
* @param AesKey AES256金鑰字串
* @return 轉換成Base64資料
*/
public String encrypt(Map rawData, String AesKey) {
try {
ObjectMapper objMapper = new ObjectMapper();
byte[] data = objMapper.writeValueAsString(rawData).getBytes(UTF_8);
byte[] key = AesKey.getBytes(UTF_8);
// 16 bytes is the IV size for AES256
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
// 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);
Base64.Encoder encoder = Base64.getEncoder();
String base64 = encoder.encodeToString(outBuf2);
return base64;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
/**
* 資料 POST 到主機
* @param qstr 串接資料
* @return 服務回傳JSON資訊
*/
public String post(String qstr) {
String result = "";
try {
// 資料
byte[] qstr_bytes = qstr.getBytes(StandardCharsets.UTF_8);
URL iurl = new URL(this.url);
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 + "\r\n");
}
try {
result = response.toString();
} finally {
in.close();
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return result;
}
/**
* 取得送出欄位資料
* @return POST完整資料
*/
public String getPostData() {
String postData = "";
try {
// Base64需要使用UrlEncode做傳輸
String data_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getRawData(), this.agentKey), "UTF-8");
String svr_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getService(), this.agentKey), "UTF-8");
postData = "agent_uid=" + this.agentUid + "&service="
+ svr_toUrlEncode + "&encry_data=" + data_toUrlEncode;
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return postData;
}
}
const crypto = require('crypto');
const httpRequest = require('https');
/**
* 經銷商串接-開立發票
*/
function AgentIssueInvoice() {
// 經銷商商務代號
this.agentUid = "518169081001";
// 經銷商金鑰或認證碼
this.agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
// 特約商店商務代號
this.storeUid = "289151880002";
// 串接交易位置
this.url = "https://ka.usecase.cc/api/agent";
};
/**
* 取得串接欄位資料
*/
AgentIssueInvoice.prototype.getRawData = function () {
return {
store_uid: this.storeUid,
uid: "58793",
key: "ab106dd223c66fd9258454c26e188f01",
invoice_input_type: 1,
invoice_cloud_type: 2,
invoice_mobile_code: "/NFVIAZP",
};
};
/**
* 取得服務位置
*/
AgentIssueInvoice.prototype.getService = function () {
return {
service_name: "api",
cmd: "api/issueinvoice"
};
};
/**
* AES 256 加密
*/
AgentIssueInvoice.prototype.encrypt = function (fields, key) {
let eData = JSON.stringify(fields);
const blockSize = 16;
const iv = crypto.randomBytes(blockSize);
const encryptor = crypto.createCipheriv('aes-256-cbc', key, iv);
let tmpCipher = encryptor.update(Buffer.from(eData));
let finalCipher = encryptor.final();
const tempData = Buffer.concat([tmpCipher, finalCipher], tmpCipher.length + finalCipher.length);
let data = Buffer.concat([iv, tempData], iv.length + tempData.length).toString('base64');
return data;
};
/**
* 資料 POST 到主機
*/
AgentIssueInvoice.prototype.post = function (postData) {
return new Promise((res, rej) => {
let options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
rejectUnauthorized: false
};
let send_process = httpRequest.request(this.url, options, (api_res) => {
let res_data = "";
api_res.on('data', (tmp_data) => {
res_data += tmp_data;
});
api_res.on('end', () => {
res(res_data);
});
});
send_process.write(JSON.stringify(postData));
send_process.end();
});
};
/**
* 取得送出欄位資料
*/
AgentIssueInvoice.prototype.getPostData = function () {
return {
"agent_uid": this.agentUid,
"service": this.encrypt(this.getService(), this.agentKey),
"encry_data": this.encrypt(this.getRawData(), this.agentKey)
};
};
/**
* 執行
*/
AgentIssueInvoice.prototype.run = async function () {
json = await this.post(this.getPostData())
console.log(json);
};
AgentIssueInvoice = new AgentIssueInvoice();
AgentIssueInvoice.run();
# -*- coding: utf-8 -*-
import json
import base64
import requests
from Crypto.Cipher import AES
from Crypto.Util import Padding
from Crypto.Random import get_random_bytes
"""經銷商串接-開立發票
"""
class AgentIssueInvoice:
# 經銷商商務代號
agentUid = "518169081001";
# 經銷商金鑰或認證碼
agentKey = b"0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
# 特約商店商務代號
storeUid = "289151880002"
# 串接交易位置
url = "https://ka.usecase.cc/api/agent"
def getRawData(self):
"""取得串接欄位資料
Returns:
{dict}: 欄位資料
"""
rawData = {
'store_uid': self.storeUid,
'uid': "58793",
'key': "ab106dd223c66fd9258454c26e188f01",
'invoice_input_type': 1,
'invoice_cloud_type': 2,
'invoice_mobile_code': "/NFVIAZP",
}
return rawData
def getService(self):
"""取得服務位置
Returns:
{dict}: 服務位置資料
"""
return {
'service_name': 'api',
'cmd': 'api/issueinvoice'
}
def encrypt(self, fields, key):
"""AES 256 加密
Args:
fields {dict}: 欄位資料
key {bytes}: AES金鑰
Returns:
{string}: 加密資料
"""
data = json.dumps(fields, separators=(',', ':'))
data = Padding.pad(data.encode('utf-8'), AES.block_size)
iv = get_random_bytes(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
data = cipher.encrypt(data)
data = base64.b64encode(iv + data)
return data
def post(self, postData):
"""資料 POST 到主機
Args:
postData {dict}: 欄位資料
Returns:
{string}: JSON資料
"""
result = requests.post(self.url, postData)
return result.text
def getPostData(self):
"""取得送出欄位資料
Returns:
{dict}: 欄位資料
"""
postData = {
'agent_uid': self.agentUid,
'service': self.encrypt(self.getService(), self.agentKey),
'encry_data': self.encrypt(self.getRawData(), self.agentKey)
}
return postData
def run(self):
"""執行
"""
json = self.post(self.getPostData())
print(json)
AgentIssueInvoice = AgentIssueInvoice()
AgentIssueInvoice.run()
回傳 JSON 結構如下:
{
"uid": "107208",
"key": "4b67dabc483338a981d2c3c30a381172",
"code": "B200",
"msg": "發票處理完成",
"order_id": "1234567890",
"actual_cost": 10,
"actual_currency": "TWD",
"state": 2,
"date": "20220427160043",
"wordtrack": "JH",
"number": "00000242",
"rand_code": "3385",
"seller_ban": "28915188",
"buyer_ban": "",
"left_qrcode": "JH00000242111042733850000000a0000000a0000000028915188AzucYuoKTbrLpvBKlKWNMA==:**********:1:1:1:商品名稱:1:10:",
"middle_barcode": "11104JH000002423385",
"right_qrcode": "**",
"title_type": 1,
"title": "123",
"sales_amount": "10",
"tax_amount": "0",
"order_detail": "[{\"Description\":\"商品名稱\",\"Quantity\":\"1\",\"UnitPrice\":\"10\",\"Amount\":\"10\"}]",
"ratetype": 1,
"input_type": 1,
"echo_0": "",
"echo_1": "",
"echo_2": "",
"echo_3": "",
"echo_4": ""
}經銷商『電子發票開立』參數說明
| 欄位 | 型態 | 說明 |
|---|---|---|
| agent_uid | string(16) | 經銷商商務代號 |
| service | text | {"service_name": "api", "cmd": "api\/issueinvoice"}JSON格式,AES256加密資料 |
| encry_data | text | 『電子發票開立』欄位參考 JSON格式,AES256加密資料 |
『電子發票開立』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| store_uid | string | 特約商店編號(金鑰中心會驗證) | |
| key | string | 特約商店驗證碼 (store_token) | |
| uid | string | 訂單編號(UID) | |
| payer_mail | string | 訂購人電子郵件,如果原訂單沒有則以此為主,如果原訂單有mail,會以原訂單的電子郵件為主,自動忽略此欄位 | |
| invoice_input_type | integer | 電子發票開立類型 | 『電子發票開立類型』值參考 |
| invoice_cloud_type | string | 「雲端發票」類型 | 當invoice_input_type為1,此狀態才有效 『雲端發票類型』值參考 |
| invoice_tax_id | string | 統一編號 | 當invoice_input_type為1,此欄位才有效,非必要 |
| invoice_mobile_code | string | 手機條碼 | 當invoice_cloud_type為2,此欄位才有效 |
| invoice_natural_person | string | 自然人憑證條碼 | 當invoice_cloud_type為3,此欄位才有效 |
| invoice_love_code | string | 愛心碼 | 當invoice_input_type為2,此欄位才有效 |
| invoice_b2b_title | string | 發票抬頭 | 當invoice_input_type為3時,此欄位才有效 |
| invoice_b2b_id | string | 統一編號 | 當invoice_input_type為3時,此欄位才有效 |
| invoice_b2b_post_zone | string | 發票郵遞區號 | 當invoice_input_type為3時,此欄位才有效,非必須 |
| invoice_b2b_address | string | 發票地址 | 當invoice_input_type為3時,此欄位才有效 |
『電子發票開立』回傳欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| uid | string | 原MYPAYLINK 之交易流水號 | |
| key | string | 交易驗証碼 | |
| code | string | 主要交易回傳碼(retcode) | |
| msg | string | 主要交易回傳碼(retcode) | |
| order_id | string | 貴特店系統的訂單編號 | |
| actual_cost | string | 實際交易金額 | |
| actual_currency | string | 實際交易幣別 | |
| state | string | 發票開立狀態 0.不處理(預設) 1等候處理中,2發票處理成功 3.發票處理失敗 4.作癈 | |
| state_msg | string | 發票開立狀態訊息 | |
| 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 | 電子發票標題內容 | |
| amount | string | 電子發票開立總額 | |
| sales_amount | string | 電子發票銷售額 | |
| tax_amount | string | 電子發票稅額 | |
| order_detail | string | 電子發票開立之產品詳細資訊(JSON格式) | 『商品細項』值參考 |
| ratetype | integer | 電子發票稅率別 | 『電子發票稅率別』值參考 |
| input_type | integer | 電子發票開立類型 | 『電子發票開立類型』值參考 |
| echo_0 | string | 自訂回傳參數 1 | |
| echo_1 | string | 自訂回傳參數 2 | |
| echo_2 | string | 自訂回傳參數 3 | |
| echo_3 | string | 自訂回傳參數 4 | |
| echo_4 | string | 自訂回傳參數 5 |
電子發票查詢
查詢目前電子發票即時的開立狀態,而交易查詢則包含訂單完整資訊。您可以依您需求作個別查詢。符合查詢規則時,則會回傳相關交易欄位,不符合查詢條件則回傳原查詢欄位。須符合條件才會回傳正確的查詢結果,交易查詢除了提供單筆查詢,也提供一次多筆查詢。
<?php
/**
* 經銷商串接-發票查詢
*/
final class AgentInvoice
{
/**
* 經銷商商務代號
* @var string
*/
public $agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
* @var string
*/
public $agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號(代特約商店發動)
* @var string
*/
public $storeUid = "289151880002";
/**
* 串接交易位置
* @var string
*/
public $url = "https://ka.usecase.cc/api/agent";
/**
* 取得串接欄位資料
* @return array
*/
public function getRawData()
{
$rawData = array();
$rawData['uid'] = "59665";
$rawData['key'] = "c011e403fa73b088ca3d50aacfa9c43a";
return $rawData;
}
/**
* 取得服務位置
* @return array
*/
public function getService()
{
return array(
'service_name' => 'api',
'cmd' => 'api/invoice'
);
}
/**
* AES 256 加密
* @param array $fields
* @param string $key
* @return string
*/
public 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;
}
/**
* 資料 POST 到主機
* @param array $postData
* @return mixed
*/
public function post($postData = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* 取得送出欄位資料
* @return array
*/
public function getPostData ()
{
$postData = array();
$postData['agent_uid'] = $this->agentUid;
$postData['service'] = $this->encrypt($this->getService(), $this->agentKey);
$postData['encry_data'] = $this->encrypt($this->getRawData(), $this->agentKey);
return $postData;
}
/**
* 執行
*/
public function run()
{
$json = $this->post($this->getPostData());
echo $json;
}
}
$AgentInvoice = new AgentInvoice();
$AgentInvoice->run();
?>
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Dynamic;
/// <summary>
/// 建議使用.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也可能無法使用
/// </summary>
namespace MyPay {
/// <summary>
/// 經銷商串接-發票查詢
/// </summary>
public class AgentInvoice {
/// <summary>
/// 經銷商商務代號
/// </summary>
public string agentUid = "518169081001";
/// <summary>
/// 經銷商金鑰或認證碼
/// </summary>
public string agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/// <summary>
/// 特約商店商務代號
/// </summary>
public string storeUid = "289151880002";
/// <summary>
/// 串接交易位置
/// </summary>
public string url = "https://ka.usecase.cc/api/agent";
/// <summary>
/// 執行
/// </summary>
static void Main() {
AgentInvoice simulator = new AgentInvoice();
//僅限走https的Tls 1.2以上版本
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//發送至遠端
var result = simulator.Post(simulator.GetPostData());
System.Console.WriteLine(result);
}
/// <summary>
/// 取得串接欄位資料
/// </summary>
private dynamic GetRawData() {
dynamic rawData = new ExpandoObject();
rawData.uid = "59665";
rawData.key = "c011e403fa73b088ca3d50aacfa9c43a";
return rawData;
}
/// <summary>
/// 取得服務位置
/// </summary>
private ServiceRequest GetService() {
ServiceRequest rawData = new ServiceRequest();
rawData.service_name = "api";
rawData.cmd = "api/invoice";
return rawData;
}
/// <summary>
/// 取得送出欄位資料
/// </summary>
private NameValueCollection GetPostData() {
string data_json = JsonConvert.SerializeObject(GetRawData(), Formatting.None);
string svr_json = JsonConvert.SerializeObject(GetService(), Formatting.None);; //依API種類調整
//產生AES向量
var IV = GetBytesIV();
//進行加密
var data_encode = Encrypt(data_json, this.agentKey, IV);
var svr_encode = Encrypt(svr_json, this.agentKey, IV);
//請注意使用的 Http Post 套件是否會自動加上UrlEncode,本Post範例為原始方式,故須加上UrlEncode
//若自行使用的套件會自動補上UrlEncode,則請忽略下面的UrlEncode,避免做了兩次UrlEncode
string data_toUrlEncode = HttpUtility.UrlEncode(data_encode);
string svr_toUrlEncode = HttpUtility.UrlEncode(svr_encode);
NameValueCollection postData = new NameValueCollection();
postData["agent_uid"] = this.agentUid;
postData["service"] = svr_toUrlEncode;
postData["encry_data"] = data_toUrlEncode;
return postData;
}
/// <summary>
/// AES 256 加密
/// </summary>
/// <param name="data"></param>
/// <param name="key"></param>
/// <param name="byteIV"></param>
/// <returns></returns>
private string Encrypt(string data, string key, byte[] byteIV) {
var byteKey = System.Text.Encoding.UTF8.GetBytes(key);
var enBytes = AES_Encrypt(data, byteKey, byteIV);
return Convert.ToBase64String(BytesAdd(byteIV, enBytes));
}
/// <summary>
/// AES 256 加密處理
/// </summary>
/// <param name="original"></param>
/// <param name="key"></param>
/// <param name="iv"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 轉換Bytes
/// </summary>
/// <param name="a"></param>
/// <param name="arryB"></param>
/// <returns></returns>
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();
}
/// <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;
}
/// <summary>
/// 資料 POST 到主機
/// </summary>
/// <param name="pars"></param>
/// <returns></returns>
private string Post(NameValueCollection pars) {
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(this.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>
/// 串接服務請求欄位
/// </summary>
public class ServiceRequest {
public string service_name { get; set; }
public string cmd { get; set; }
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URLEncoder;
import java.util.*;
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 static java.nio.charset.StandardCharsets.UTF_8;
import org.spongycastle.crypto.engines.AESEngine;
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 java.security.SecureRandom;
/**
* 經銷商串接-發票查詢
* 1. jackson-core 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
* 2. jackson-databind 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
* 3. jackson-annotations 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
* 4. Spongy Castle 下載 https://mvnrepository.com/artifact/com.madgag.spongycastle/core
*/
public class AgentInvoice {
/**
* 經銷商商務代號
*/
String agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
*/
String agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號
*/
String storeUid = "289151880002";
/**
* 串接交易位置
*/
String url = "https://ka.usecase.cc/api/agent";
/**
* 執行
* @param args
*/
public static void main(String[] args) {
AgentInvoice simulator = new AgentInvoice();
String json = simulator.post(simulator.getPostData());
System.out.print(json);
}
@SuppressWarnings(value = { "unchecked", "deprecation" })
/**
* 取得串接欄位資料
* @return 串接原始資料
*/
public Map getRawData() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("uid", "59665");
rawData.put("key", "c011e403fa73b088ca3d50aacfa9c43a");
return rawData;
}
/**
* 取得服務位置
* @return 串接服務資料
*/
public Map getService() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("service_name", "api");
rawData.put("cmd", "api/invoice");
return rawData;
}
/**
* AES 256 加密
* @param rawData 原始資料
* @param AesKey AES256金鑰字串
* @return 轉換成Base64資料
*/
public String encrypt(Map rawData, String AesKey) {
try {
ObjectMapper objMapper = new ObjectMapper();
byte[] data = objMapper.writeValueAsString(rawData).getBytes(UTF_8);
byte[] key = AesKey.getBytes(UTF_8);
// 16 bytes is the IV size for AES256
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
// 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);
Base64.Encoder encoder = Base64.getEncoder();
String base64 = encoder.encodeToString(outBuf2);
return base64;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
/**
* 資料 POST 到主機
* @param qstr 串接資料
* @return 服務回傳JSON資訊
*/
public String post(String qstr) {
String result = "";
try {
// 資料
byte[] qstr_bytes = qstr.getBytes(StandardCharsets.UTF_8);
URL iurl = new URL(this.url);
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 + "\r\n");
}
try {
result = response.toString();
} finally {
in.close();
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return result;
}
/**
* 取得送出欄位資料
* @return POST完整資料
*/
public String getPostData() {
String postData = "";
try {
// Base64需要使用UrlEncode做傳輸
String data_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getRawData(), this.agentKey), "UTF-8");
String svr_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getService(), this.agentKey), "UTF-8");
postData = "agent_uid=" + this.agentUid + "&service="
+ svr_toUrlEncode + "&encry_data=" + data_toUrlEncode;
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return postData;
}
}
const crypto = require('crypto');
const httpRequest = require('https');
/**
* 經銷商串接-發票查詢
*/
function AgentInvoice() {
// 經銷商商務代號
this.agentUid = "518169081001";
// 經銷商金鑰或認證碼
this.agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
// 特約商店商務代號
this.storeUid = "289151880002";
// 串接交易位置
this.url = "https://ka.usecase.cc/api/agent";
};
/**
* 取得串接欄位資料
*/
AgentInvoice.prototype.getRawData = function () {
return {
uid: "59665",
key: "c011e403fa73b088ca3d50aacfa9c43a",
};
};
/**
* 取得服務位置
*/
AgentInvoice.prototype.getService = function () {
return {
service_name: "api",
cmd: "api/invoice"
};
};
/**
* AES 256 加密
*/
AgentInvoice.prototype.encrypt = function (fields, key) {
let eData = JSON.stringify(fields);
const blockSize = 16;
const iv = crypto.randomBytes(blockSize);
const encryptor = crypto.createCipheriv('aes-256-cbc', key, iv);
let tmpCipher = encryptor.update(Buffer.from(eData));
let finalCipher = encryptor.final();
const tempData = Buffer.concat([tmpCipher, finalCipher], tmpCipher.length + finalCipher.length);
let data = Buffer.concat([iv, tempData], iv.length + tempData.length).toString('base64');
return data;
};
/**
* 資料 POST 到主機
*/
AgentInvoice.prototype.post = function (postData) {
return new Promise((res, rej) => {
let options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
rejectUnauthorized: false
};
let send_process = httpRequest.request(this.url, options, (api_res) => {
let res_data = "";
api_res.on('data', (tmp_data) => {
res_data += tmp_data;
});
api_res.on('end', () => {
res(res_data);
});
});
send_process.write(JSON.stringify(postData));
send_process.end();
});
};
/**
* 取得送出欄位資料
*/
AgentInvoice.prototype.getPostData = function () {
return {
"agent_uid": this.agentUid,
"service": this.encrypt(this.getService(), this.agentKey),
"encry_data": this.encrypt(this.getRawData(), this.agentKey)
};
};
/**
* 執行
*/
AgentInvoice.prototype.run = async function () {
json = await this.post(this.getPostData())
console.log(json);
};
AgentInvoice = new AgentInvoice();
AgentInvoice.run();
# -*- coding: utf-8 -*-
import json
import base64
import requests
from Crypto.Cipher import AES
from Crypto.Util import Padding
from Crypto.Random import get_random_bytes
"""經銷商串接-發票查詢
"""
class AgentInvoice:
# 經銷商商務代號
agentUid = "518169081001";
# 經銷商金鑰或認證碼
agentKey = b"0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
# 特約商店商務代號
storeUid = "289151880002"
# 串接交易位置
url = "https://ka.usecase.cc/api/agent"
def getRawData(self):
"""取得串接欄位資料
Returns:
{dict}: 欄位資料
"""
rawData = {
'uid': "59665",
'key': "c011e403fa73b088ca3d50aacfa9c43a",
}
return rawData
def getService(self):
"""取得服務位置
Returns:
{dict}: 服務位置資料
"""
return {
'service_name': 'api',
'cmd': 'api/invoice'
}
def encrypt(self, fields, key):
"""AES 256 加密
Args:
fields {dict}: 欄位資料
key {bytes}: AES金鑰
Returns:
{string}: 加密資料
"""
data = json.dumps(fields, separators=(',', ':'))
data = Padding.pad(data.encode('utf-8'), AES.block_size)
iv = get_random_bytes(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
data = cipher.encrypt(data)
data = base64.b64encode(iv + data)
return data
def post(self, postData):
"""資料 POST 到主機
Args:
postData {dict}: 欄位資料
Returns:
{string}: JSON資料
"""
result = requests.post(self.url, postData)
return result.text
def getPostData(self):
"""取得送出欄位資料
Returns:
{dict}: 欄位資料
"""
postData = {
'agent_uid': self.agentUid,
'service': self.encrypt(self.getService(), self.agentKey),
'encry_data': self.encrypt(self.getRawData(), self.agentKey)
}
return postData
def run(self):
"""執行
"""
json = self.post(self.getPostData())
print(json)
AgentInvoice = AgentInvoice()
AgentInvoice.run()
回傳 JSON 結構如下:
{
"uid": 34799,
"key": "c23dd140aa9536eb4c09ef053171110f",
"prc": "250",
"order_id": "1234567890",
"cost": 1,
"currency": "TWD",
"actual_cost": 1,
"actual_currency": "TWD",
"state": 2,
"date": "20181101100330",
"wordtrack": "AA",
"number": "12345678",
"rand_code": "",
"seller_ban": "",
"buyer_ban": "",
"left_qrcode": "",
"middle_barcode": "",
"right_qrcode": "",
"title_type": 1,
"title": "",
"print_type": 0,
"print_device": 0,
"amount": "0",
"sales_amount": "0",
"tax_amount": "0",
"order_detail": "[]",
"ratetype": 1,
"input_type": 2,
"cloud_type": "",
"mobile_code": "",
"tax_id": "",
"natural_person": "",
"m_post_zone": "",
"m_address": "",
"love_code": "241",
"b2b_title": "",
"b2b_id": "",
"b2b_post_zone": "",
"b2b_address": "",
"allowance": [],
"group_id": "",
"payment_name": "",
"nois": "",
"echo_0": "",
"echo_1": "",
"echo_2": "",
"echo_3": "",
"echo_4": ""
}經銷商『電子發票查詢』參數說明
| 欄位 | 型態 | 說明 |
|---|---|---|
| agent_uid | string(16) | 經銷商商務代號 |
| service | text | {"service_name": "api", "cmd": "api\/invoice"}JSON格式,AES256加密資料 |
| encry_data | text | 『電子發票查詢』欄位參考 JSON格式,AES256加密資料 |
『電子發票查詢』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| 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 | |
| count | int | 發票剩餘張數,此處為打ka.usecase.cc與ka.mypay.tw才會回傳 |
代收款核銷撥款請求
使用情境:當經銷商經營平台服務,為確保產品或服務已經交付完畢後,款項才撥付給特約商店時使用。
註:消費者若已退款,也必須發動核銷
<?php
/**
* 經銷商串接-代收款核銷撥款請求
*/
final class AgentRequestPayment
{
/**
* 經銷商商務代號
* @var string
*/
public $agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
* @var string
*/
public $agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號(代特約商店發動)
* @var string
*/
public $storeUid = "289151880002";
/**
* 串接交易位置
* @var string
*/
public $url = "https://ka.usecase.cc/api/agent";
/**
* 取得串接欄位資料
* @return array
*/
public function getRawData()
{
$rawData = array();
$rawData['store_uid'] = $this->storeUid;
$rawData['uid'] = "95853";
$rawData['key'] = "92b6934bc43d1de1b08d69ae6ca38f46";
$rawData['reimbursement_date'] = "20211102";
$rawData['completion_date'] = "20211102";
$rawData['service_type'] = 1;
$rawData['freight_name'] = "新竹物流";
$rawData['freight_no'] = "5432123456";
return $rawData;
}
/**
* 取得服務位置
* @return array
*/
public function getService()
{
return array(
'service_name' => 'api',
'cmd' => 'api/requestpayment'
);
}
/**
* AES 256 加密
* @param array $fields
* @param string $key
* @return string
*/
public 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;
}
/**
* 資料 POST 到主機
* @param array $postData
* @return mixed
*/
public function post($postData = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* 取得送出欄位資料
* @return array
*/
public function getPostData ()
{
$postData = array();
$postData['agent_uid'] = $this->agentUid;
$postData['service'] = $this->encrypt($this->getService(), $this->agentKey);
$postData['encry_data'] = $this->encrypt($this->getRawData(), $this->agentKey);
return $postData;
}
/**
* 執行
*/
public function run()
{
$json = $this->post($this->getPostData());
echo $json;
}
}
$AgentRequestPayment = new AgentRequestPayment();
$AgentRequestPayment->run();
?>
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Dynamic;
/// <summary>
/// 建議使用.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也可能無法使用
/// </summary>
namespace MyPay {
/// <summary>
/// 經銷商串接-代收款核銷撥款請求
/// </summary>
public class AgentRequestPayment {
/// <summary>
/// 經銷商商務代號
/// </summary>
public string agentUid = "518169081001";
/// <summary>
/// 經銷商金鑰或認證碼
/// </summary>
public string agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/// <summary>
/// 特約商店商務代號
/// </summary>
public string storeUid = "289151880002";
/// <summary>
/// 串接交易位置
/// </summary>
public string url = "https://ka.usecase.cc/api/agent";
/// <summary>
/// 執行
/// </summary>
static void Main() {
AgentRequestPayment simulator = new AgentRequestPayment();
//僅限走https的Tls 1.2以上版本
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//發送至遠端
var result = simulator.Post(simulator.GetPostData());
System.Console.WriteLine(result);
}
/// <summary>
/// 取得串接欄位資料
/// </summary>
private dynamic GetRawData() {
dynamic rawData = new ExpandoObject();
rawData.store_uid = this.storeUid;
rawData.uid = "95853";
rawData.key = "92b6934bc43d1de1b08d69ae6ca38f46";
rawData.reimbursement_date = "20211102";
rawData.completion_date = "20211102";
rawData.service_type = 1;
rawData.freight_name = "新竹物流";
rawData.freight_no = "5432123456";
return rawData;
}
/// <summary>
/// 取得服務位置
/// </summary>
private ServiceRequest GetService() {
ServiceRequest rawData = new ServiceRequest();
rawData.service_name = "api";
rawData.cmd = "api/requestpayment";
return rawData;
}
/// <summary>
/// 取得送出欄位資料
/// </summary>
private NameValueCollection GetPostData() {
string data_json = JsonConvert.SerializeObject(GetRawData(), Formatting.None);
string svr_json = JsonConvert.SerializeObject(GetService(), Formatting.None);; //依API種類調整
//產生AES向量
var IV = GetBytesIV();
//進行加密
var data_encode = Encrypt(data_json, this.agentKey, IV);
var svr_encode = Encrypt(svr_json, this.agentKey, IV);
//請注意使用的 Http Post 套件是否會自動加上UrlEncode,本Post範例為原始方式,故須加上UrlEncode
//若自行使用的套件會自動補上UrlEncode,則請忽略下面的UrlEncode,避免做了兩次UrlEncode
string data_toUrlEncode = HttpUtility.UrlEncode(data_encode);
string svr_toUrlEncode = HttpUtility.UrlEncode(svr_encode);
NameValueCollection postData = new NameValueCollection();
postData["agent_uid"] = this.agentUid;
postData["service"] = svr_toUrlEncode;
postData["encry_data"] = data_toUrlEncode;
return postData;
}
/// <summary>
/// AES 256 加密
/// </summary>
/// <param name="data"></param>
/// <param name="key"></param>
/// <param name="byteIV"></param>
/// <returns></returns>
private string Encrypt(string data, string key, byte[] byteIV) {
var byteKey = System.Text.Encoding.UTF8.GetBytes(key);
var enBytes = AES_Encrypt(data, byteKey, byteIV);
return Convert.ToBase64String(BytesAdd(byteIV, enBytes));
}
/// <summary>
/// AES 256 加密處理
/// </summary>
/// <param name="original"></param>
/// <param name="key"></param>
/// <param name="iv"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 轉換Bytes
/// </summary>
/// <param name="a"></param>
/// <param name="arryB"></param>
/// <returns></returns>
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();
}
/// <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;
}
/// <summary>
/// 資料 POST 到主機
/// </summary>
/// <param name="pars"></param>
/// <returns></returns>
private string Post(NameValueCollection pars) {
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(this.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>
/// 串接服務請求欄位
/// </summary>
public class ServiceRequest {
public string service_name { get; set; }
public string cmd { get; set; }
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URLEncoder;
import java.util.*;
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 static java.nio.charset.StandardCharsets.UTF_8;
import org.spongycastle.crypto.engines.AESEngine;
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 java.security.SecureRandom;
/**
* 經銷商串接-代收款核銷撥款請求
* 1. jackson-core 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
* 2. jackson-databind 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
* 3. jackson-annotations 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
* 4. Spongy Castle 下載 https://mvnrepository.com/artifact/com.madgag.spongycastle/core
*/
public class AgentRequestPayment {
/**
* 經銷商商務代號
*/
String agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
*/
String agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號
*/
String storeUid = "289151880002";
/**
* 串接交易位置
*/
String url = "https://ka.usecase.cc/api/agent";
/**
* 執行
* @param args
*/
public static void main(String[] args) {
AgentRequestPayment simulator = new AgentRequestPayment();
String json = simulator.post(simulator.getPostData());
System.out.print(json);
}
@SuppressWarnings(value = { "unchecked", "deprecation" })
/**
* 取得串接欄位資料
* @return 串接原始資料
*/
public Map getRawData() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("store_uid", this.storeUid);
rawData.put("uid", "95853");
rawData.put("key", "92b6934bc43d1de1b08d69ae6ca38f46");
rawData.put("reimbursement_date", "20211102");
rawData.put("completion_date", "20211102");
rawData.put("service_type", 1);
rawData.put("freight_name", "新竹物流");
rawData.put("freight_no", "5432123456");
return rawData;
}
/**
* 取得服務位置
* @return 串接服務資料
*/
public Map getService() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("service_name", "api");
rawData.put("cmd", "api/requestpayment");
return rawData;
}
/**
* AES 256 加密
* @param rawData 原始資料
* @param AesKey AES256金鑰字串
* @return 轉換成Base64資料
*/
public String encrypt(Map rawData, String AesKey) {
try {
ObjectMapper objMapper = new ObjectMapper();
byte[] data = objMapper.writeValueAsString(rawData).getBytes(UTF_8);
byte[] key = AesKey.getBytes(UTF_8);
// 16 bytes is the IV size for AES256
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
// 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);
Base64.Encoder encoder = Base64.getEncoder();
String base64 = encoder.encodeToString(outBuf2);
return base64;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
/**
* 資料 POST 到主機
* @param qstr 串接資料
* @return 服務回傳JSON資訊
*/
public String post(String qstr) {
String result = "";
try {
// 資料
byte[] qstr_bytes = qstr.getBytes(StandardCharsets.UTF_8);
URL iurl = new URL(this.url);
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 + "\r\n");
}
try {
result = response.toString();
} finally {
in.close();
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return result;
}
/**
* 取得送出欄位資料
* @return POST完整資料
*/
public String getPostData() {
String postData = "";
try {
// Base64需要使用UrlEncode做傳輸
String data_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getRawData(), this.agentKey), "UTF-8");
String svr_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getService(), this.agentKey), "UTF-8");
postData = "agent_uid=" + this.agentUid + "&service="
+ svr_toUrlEncode + "&encry_data=" + data_toUrlEncode;
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return postData;
}
}
const crypto = require('crypto');
const httpRequest = require('https');
/**
* 經銷商串接-代收款核銷撥款請求
*/
function AgentRequestPayment() {
// 經銷商商務代號
this.agentUid = "518169081001";
// 經銷商金鑰或認證碼
this.agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
// 特約商店商務代號
this.storeUid = "289151880002";
// 串接交易位置
this.url = "https://ka.usecase.cc/api/agent";
};
/**
* 取得串接欄位資料
*/
AgentRequestPayment.prototype.getRawData = function () {
return {
store_uid: this.storeUid,
uid: "95853",
key: "92b6934bc43d1de1b08d69ae6ca38f46",
reimbursement_date: "20211102",
completion_date: "20211102",
service_type: 1,
freight_name: "新竹物流",
freight_no: "5432123456",
};
};
/**
* 取得服務位置
*/
AgentRequestPayment.prototype.getService = function () {
return {
service_name: "api",
cmd: "api/requestpayment"
};
};
/**
* AES 256 加密
*/
AgentRequestPayment.prototype.encrypt = function (fields, key) {
let eData = JSON.stringify(fields);
const blockSize = 16;
const iv = crypto.randomBytes(blockSize);
const encryptor = crypto.createCipheriv('aes-256-cbc', key, iv);
let tmpCipher = encryptor.update(Buffer.from(eData));
let finalCipher = encryptor.final();
const tempData = Buffer.concat([tmpCipher, finalCipher], tmpCipher.length + finalCipher.length);
let data = Buffer.concat([iv, tempData], iv.length + tempData.length).toString('base64');
return data;
};
/**
* 資料 POST 到主機
*/
AgentRequestPayment.prototype.post = function (postData) {
return new Promise((res, rej) => {
let options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
rejectUnauthorized: false
};
let send_process = httpRequest.request(this.url, options, (api_res) => {
let res_data = "";
api_res.on('data', (tmp_data) => {
res_data += tmp_data;
});
api_res.on('end', () => {
res(res_data);
});
});
send_process.write(JSON.stringify(postData));
send_process.end();
});
};
/**
* 取得送出欄位資料
*/
AgentRequestPayment.prototype.getPostData = function () {
return {
"agent_uid": this.agentUid,
"service": this.encrypt(this.getService(), this.agentKey),
"encry_data": this.encrypt(this.getRawData(), this.agentKey)
};
};
/**
* 執行
*/
AgentRequestPayment.prototype.run = async function () {
json = await this.post(this.getPostData())
console.log(json);
};
AgentRequestPayment = new AgentRequestPayment();
AgentRequestPayment.run();
<?php
/**
* 經銷商串接-代收款核銷撥款請求
*/
final class AgentRequestPayment
{
/**
* 經銷商商務代號
* @var string
*/
public $agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
* @var string
*/
public $agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 特約商店商務代號(代特約商店發動)
* @var string
*/
public $storeUid = "289151880002";
/**
* 串接交易位置
* @var string
*/
public $url = "https://ka.usecase.cc/api/agent";
/**
* 取得串接欄位資料
* @return array
*/
public function getRawData()
{
$rawData = array();
$rawData['store_uid'] = $this->storeUid;
$rawData['uid'] = "95853";
$rawData['key'] = "92b6934bc43d1de1b08d69ae6ca38f46";
$rawData['reimbursement_date'] = "20211102";
$rawData['completion_date'] = "20211102";
$rawData['service_type'] = 1;
$rawData['freight_name'] = "新竹物流";
$rawData['freight_no'] = "5432123456";
return $rawData;
}
/**
* 取得服務位置
* @return array
*/
public function getService()
{
return array(
'service_name' => 'api',
'cmd' => 'api/requestpayment'
);
}
/**
* AES 256 加密
* @param array $fields
* @param string $key
* @return string
*/
public 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;
}
/**
* 資料 POST 到主機
* @param array $postData
* @return mixed
*/
public function post($postData = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* 取得送出欄位資料
* @return array
*/
public function getPostData ()
{
$postData = array();
$postData['agent_uid'] = $this->agentUid;
$postData['service'] = $this->encrypt($this->getService(), $this->agentKey);
$postData['encry_data'] = $this->encrypt($this->getRawData(), $this->agentKey);
return $postData;
}
/**
* 執行
*/
public function run()
{
$json = $this->post($this->getPostData());
echo $json;
}
}
$AgentRequestPayment = new AgentRequestPayment();
$AgentRequestPayment->run();
?>
回傳 JSON 結構如下:
{
"code": "100",
"msg": "請款日期應為今日起(含)兩個月內",
"appropriation_date": "",
"store_gateway_fee": 0,
"domestic_store_sms_fee": 0,
"foreign_store_sms_fee": 0
}經銷商『代收款核銷撥款請求』參數說明
| 欄位 | 型態 | 說明 |
|---|---|---|
| agent_uid | string(16) | 經銷商商務代號 |
| service | text | {"service_name": "api", "cmd": "api\/requestpayment"}JSON格式,AES256加密資料 |
| encry_data | text | 『代收款核銷撥款請求』欄位參考 JSON格式,AES256加密資料 |
『代收款核銷撥款請求』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| store_uid | string | 特約商店編號 | 必填 |
| uid | string | MYPAY LINK之交易流水號 | 必填 |
| key | string | 交易驗証碼 | 必填 |
| string | 核銷日期、請款日(限今日起兩個月內)(格式YYYYMMDD) | 必填 | |
| completion_date | string | 商品與服務交付完成日期(格式YYYYMMDD) | 必填 |
| service_type | integer | 服務提供方式 1.貨運2.課程3.票券4.講座活動 | 必要 『經銷商代收款核銷服務提供方式』值參考 |
| freight_name | string | 貨運廠商名稱(服務方式為貨運時必填) | |
| freight_no | string | 貨運編號(服務方式為貨運時必填) |
『代收款核銷撥款請求』回傳欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| code | string | 交易回傳碼(B200或B500或100) | |
| msg | string | 回傳訊息 | |
| appropriation_date | string | 預計撥款日 | |
| store_gateway_fee | float | 金流服務費 | |
| domestic_store_sms_fee | float | 國內簡訊費 | |
| foreign_store_sms_fee | float | 國外簡訊費 |
特約商店可用支付工具查詢
可查詢目前特約商店所支援的支付工具有哪些,需注意當支付工具有設定不到一定的金額不能使用時,則cost必須要達到該金額以上,否則無法查詢到
<?php
/**
* 經銷商串接-查詢特約商店支援之支付方式
*/
final class AgentSupportPayMode
{
/**
* 經銷商商務代號
* @var string
*/
public $agentUid = "A1234567891002";
/**
* 經銷商金鑰或認證碼
* @var string
*/
public $agentKey = "nq8KL8qNNCW12A3TBfAp4lU0y3PED8IQ";
/**
* 特約商店商務代號(代特約商店發動)
* @var string
*/
public $storeUid = "289151880002";
/**
* 串接交易位置
* @var string
*/
public $url = "https://ka.usecase.cc/api/agent";
/**
* 取得串接欄位資料
* @return array
*/
public function getRawData()
{
$rawData = array();
$rawData['store_uid'] = $this->storeUid;
$rawData['cost'] = "1000";
$rawData['currency'] = "TWD";
return $rawData;
}
/**
* 取得服務位置
* @return array
*/
public function getService()
{
return array(
'service_name' => 'api',
'cmd' => 'api/paymentsupportpaymode'
);
}
/**
* AES 256 加密
* @param array $fields
* @param string $key
* @return string
*/
public 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;
}
/**
* 資料 POST 到主機
* @param array $postData
* @return mixed
*/
public function post($postData = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* 取得送出欄位資料
* @return array
*/
public function getPostData ()
{
$postData = array();
$postData['agent_uid'] = $this->agentUid;
$postData['service'] = $this->encrypt($this->getService(), $this->agentKey);
$postData['encry_data'] = $this->encrypt($this->getRawData(), $this->agentKey);
return $postData;
}
/**
* 執行
*/
public function run()
{
$json = $this->post($this->getPostData());
echo $json;
}
}
$AgentSupportPayMode = new AgentSupportPayMode();
$AgentSupportPayMode->run();
?>
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Dynamic;
/// <summary>
/// 建議使用.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也可能無法使用
/// </summary>
namespace MyPay {
/// <summary>
/// 經銷商串接-查詢特約商店支援之支付方式
/// </summary>
public class AgentSupportPayMode {
/// <summary>
/// 經銷商商務代號
/// </summary>
public string agentUid = "A1234567891002";
/// <summary>
/// 經銷商金鑰或認證碼
/// </summary>
public string agentKey = "nq8KL8qNNCW12A3TBfAp4lU0y3PED8IQ";
/// <summary>
/// 特約商店商務代號
/// </summary>
public string storeUid = "289151880002";
/// <summary>
/// 串接交易位置
/// </summary>
public string url = "https://ka.usecase.cc/api/agent";
/// <summary>
/// 執行
/// </summary>
static void Main() {
AgentSupportPayMode simulator = new AgentSupportPayMode();
//僅限走https的Tls 1.2以上版本
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//發送至遠端
var result = simulator.Post(simulator.GetPostData());
System.Console.WriteLine(result);
}
/// <summary>
/// 取得串接欄位資料
/// </summary>
private dynamic GetRawData() {
dynamic rawData = new ExpandoObject();
rawData.store_uid = this.storeUid;
rawData.cost = "1000";
rawData.currency = "TWD";
return rawData;
}
/// <summary>
/// 取得服務位置
/// </summary>
private ServiceRequest GetService() {
ServiceRequest rawData = new ServiceRequest();
rawData.service_name = "api";
rawData.cmd = "api/paymentsupportpaymode";
return rawData;
}
/// <summary>
/// 取得送出欄位資料
/// </summary>
private NameValueCollection GetPostData() {
string data_json = JsonConvert.SerializeObject(GetRawData(), Formatting.None);
string svr_json = JsonConvert.SerializeObject(GetService(), Formatting.None);; //依API種類調整
//產生AES向量
var IV = GetBytesIV();
//進行加密
var data_encode = Encrypt(data_json, this.agentKey, IV);
var svr_encode = Encrypt(svr_json, this.agentKey, IV);
//請注意使用的 Http Post 套件是否會自動加上UrlEncode,本Post範例為原始方式,故須加上UrlEncode
//若自行使用的套件會自動補上UrlEncode,則請忽略下面的UrlEncode,避免做了兩次UrlEncode
string data_toUrlEncode = HttpUtility.UrlEncode(data_encode);
string svr_toUrlEncode = HttpUtility.UrlEncode(svr_encode);
NameValueCollection postData = new NameValueCollection();
postData["agent_uid"] = this.agentUid;
postData["service"] = svr_toUrlEncode;
postData["encry_data"] = data_toUrlEncode;
return postData;
}
/// <summary>
/// AES 256 加密
/// </summary>
/// <param name="data"></param>
/// <param name="key"></param>
/// <param name="byteIV"></param>
/// <returns></returns>
private string Encrypt(string data, string key, byte[] byteIV) {
var byteKey = System.Text.Encoding.UTF8.GetBytes(key);
var enBytes = AES_Encrypt(data, byteKey, byteIV);
return Convert.ToBase64String(BytesAdd(byteIV, enBytes));
}
/// <summary>
/// AES 256 加密處理
/// </summary>
/// <param name="original"></param>
/// <param name="key"></param>
/// <param name="iv"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 轉換Bytes
/// </summary>
/// <param name="a"></param>
/// <param name="arryB"></param>
/// <returns></returns>
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();
}
/// <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;
}
/// <summary>
/// 資料 POST 到主機
/// </summary>
/// <param name="pars"></param>
/// <returns></returns>
private string Post(NameValueCollection pars) {
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(this.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>
/// 串接服務請求欄位
/// </summary>
public class ServiceRequest {
public string service_name { get; set; }
public string cmd { get; set; }
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URLEncoder;
import java.util.*;
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 static java.nio.charset.StandardCharsets.UTF_8;
import org.spongycastle.crypto.engines.AESEngine;
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 java.security.SecureRandom;
/**
* 經銷商串接-查詢特約商店支援之支付方式
* 1. jackson-core 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
* 2. jackson-databind 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
* 3. jackson-annotations 下載 https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
* 4. Spongy Castle 下載 https://mvnrepository.com/artifact/com.madgag.spongycastle/core
*/
public class AgentSupportPayMode {
/**
* 經銷商商務代號
*/
String agentUid = "A1234567891002";
/**
* 經銷商金鑰或認證碼
*/
String agentKey = "nq8KL8qNNCW12A3TBfAp4lU0y3PED8IQ";
/**
* 特約商店商務代號
*/
String storeUid = "289151880002";
/**
* 串接交易位置
*/
String url = "https://ka.usecase.cc/api/agent";
/**
* 執行
* @param args
*/
public static void main(String[] args) {
AgentSupportPayMode simulator = new AgentSupportPayMode();
String json = simulator.post(simulator.getPostData());
System.out.print(json);
}
@SuppressWarnings(value = { "unchecked", "deprecation" })
/**
* 取得串接欄位資料
* @return 串接原始資料
*/
public Map getRawData() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("store_uid", this.storeUid);
rawData.put("cost", "1000");
rawData.put("currency", "TWD");
return rawData;
}
/**
* 取得服務位置
* @return 串接服務資料
*/
public Map getService() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("service_name", "api");
rawData.put("cmd", "api/paymentsupportpaymode");
return rawData;
}
/**
* AES 256 加密
* @param rawData 原始資料
* @param AesKey AES256金鑰字串
* @return 轉換成Base64資料
*/
public String encrypt(Map rawData, String AesKey) {
try {
ObjectMapper objMapper = new ObjectMapper();
byte[] data = objMapper.writeValueAsString(rawData).getBytes(UTF_8);
byte[] key = AesKey.getBytes(UTF_8);
// 16 bytes is the IV size for AES256
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
// 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);
Base64.Encoder encoder = Base64.getEncoder();
String base64 = encoder.encodeToString(outBuf2);
return base64;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 資料 POST 到主機
* @param qstr 串接資料
* @return 服務回傳JSON資訊
*/
public String post(String qstr) {
String result = "";
try {
// 資料
byte[] qstr_bytes = qstr.getBytes(StandardCharsets.UTF_8);
URL iurl = new URL(this.url);
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 + "\r\n");
}
try {
result = response.toString();
} finally {
in.close();
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return result;
}
/**
* 取得送出欄位資料
* @return POST完整資料
*/
public String getPostData() {
String postData = "";
try {
// Base64需要使用UrlEncode做傳輸
String data_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getRawData(), this.agentKey), "UTF-8");
String svr_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getService(), this.agentKey), "UTF-8");
postData = "agent_uid=" + this.agentUid + "&service="
+ svr_toUrlEncode + "&encry_data=" + data_toUrlEncode;
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return postData;
}
}
const crypto = require('crypto');
const httpRequest = require('https');
/**
* 經銷商串接-查詢特約商店支援之支付方式
*/
function AgentSupportPayMode() {
// 經銷商商務代號
this.agentUid = "A1234567891002";
// 經銷商金鑰或認證碼
this.agentKey = "nq8KL8qNNCW12A3TBfAp4lU0y3PED8IQ";
// 特約商店商務代號
this.storeUid = "289151880002";
// 串接交易位置
this.url = "https://ka.usecase.cc/api/agent";
};
/**
* 取得串接欄位資料
*/
AgentSupportPayMode.prototype.getRawData = function () {
return {
store_uid: this.storeUid,
cost: "1000",
currency: "TWD"
};
};
/**
* 取得服務位置
*/
AgentSupportPayMode.prototype.getService = function () {
return {
service_name: "api",
cmd: "api/paymentsupportpaymode"
};
};
/**
* AES 256 加密
*/
AgentSupportPayMode.prototype.encrypt = function (fields, key) {
let eData = JSON.stringify(fields);
const blockSize = 16;
const iv = crypto.randomBytes(blockSize);
const encryptor = crypto.createCipheriv('aes-256-cbc', key, iv);
let tmpCipher = encryptor.update(Buffer.from(eData));
let finalCipher = encryptor.final();
const tempData = Buffer.concat([tmpCipher, finalCipher], tmpCipher.length + finalCipher.length);
let data = Buffer.concat([iv, tempData], iv.length + tempData.length).toString('base64');
return data;
};
/**
* 資料 POST 到主機
*/
AgentSupportPayMode.prototype.post = function (postData) {
return new Promise((res, rej) => {
let options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
rejectUnauthorized: false
};
let send_process = httpRequest.request(this.url, options, (api_res) => {
let res_data = "";
api_res.on('data', (tmp_data) => {
res_data += tmp_data;
});
api_res.on('end', () => {
res(res_data);
});
});
send_process.write(JSON.stringify(postData));
send_process.end();
});
};
/**
* 取得送出欄位資料
*/
AgentSupportPayMode.prototype.getPostData = function () {
return {
"agent_uid": this.agentUid,
"service": this.encrypt(this.getService(), this.agentKey),
"encry_data": this.encrypt(this.getRawData(), this.agentKey)
};
};
/**
* 執行
*/
AgentSupportPayMode.prototype.run = async function () {
json = await this.post(this.getPostData())
console.log(json);
};
AgentSupportPayMode = new AgentSupportPayMode();
AgentSupportPayMode.run();
import json
import base64
import requests
from Crypto.Cipher import AES
from Crypto.Util import Padding
from Crypto.Random import get_random_bytes
"""經銷商串接-查詢特約商店支援之支付方式
"""
class AgentSupportPayMode:
# 經銷商商務代號
agentUid = "A1234567891002";
# 經銷商金鑰或認證碼
agentKey = b"nq8KL8qNNCW12A3TBfAp4lU0y3PED8IQ";
# 特約商店商務代號
storeUid = "289151880002"
# 串接交易位置
url = "https://ka.usecase.cc/api/agent"
def getRawData(self):
"""取得串接欄位資料
Returns:
{dict}: 欄位資料
"""
rawData = {
'store_uid': self.storeUid,
'cost': "1000",
'currency': "TWD"
}
return rawData
def getService(self):
"""取得服務位置
Returns:
{dict}: 服務位置資料
"""
return {
'service_name': 'api',
'cmd': 'api/paymentsupportpaymode'
}
def encrypt(self, fields, key):
"""AES 256 加密
Args:
fields {dict}: 欄位資料
key {bytes}: AES金鑰
Returns:
{string}: 加密資料
"""
data = json.dumps(fields, separators=(',', ':'))
data = Padding.pad(data.encode('utf-8'), AES.block_size)
iv = get_random_bytes(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
data = cipher.encrypt(data)
data = base64.b64encode(iv + data)
return data
def post(self, postData):
"""資料 POST 到主機
Args:
postData {dict}: 欄位資料
Returns:
{string}: JSON資料
"""
result = requests.post(self.url, postData)
return result.text
def getPostData(self):
"""取得送出欄位資料
Returns:
{dict}: 欄位資料
"""
postData = {
'agent_uid': self.agentUid,
'service': self.encrypt(self.getService(), self.agentKey),
'encry_data': self.encrypt(self.getRawData(), self.agentKey)
}
return postData
def run(self):
"""執行
"""
json = self.post(self.getPostData())
print(json)
AgentSupportPayMode = AgentSupportPayMode()
AgentSupportPayMode.run()
回傳 JSON 結構如下:
{
"code": "B200",
"msg": "執行成功",
"content": [
"CREDITCARD",
"CSTORECODE",
"WEBATM",
"E_COLLECTION",
"ABROAD",
"MATM",
"WECHAT",
"WECHATOFF",
"LINEPAYON",
"LINEPAYOFF",
"APPLEPAY",
"GOOGLEPAY",
"CARDLESS",
"PION",
"PIOFF",
"JKOON",
"JKOOFF",
"CASH",
"EASYWALLETON",
"EASYWALLETOFF",
"BARCODE"
]
}特約商店『可用支付工具查詢』參數說明
| 欄位 | 型態 | 說明 |
|---|---|---|
| agent_uid | string(16) | 經銷商商務代號 |
| service | text | {"service_name": "api", "cmd": "api\/paymentsupportpaymode"}JSON格式,AES256加密資料 |
| encry_data | text | 『可用支付工具查詢』欄位參考 JSON格式,AES256加密資料 |
『可用支付工具查詢』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| store_uid | string | 特約商店商務代號 | 必要 |
| cost | string | 交易金額 | 必要,最小值須為1 |
| cost | string | 預設交易幣別(預設為TWD新台幣) | 『幣別類型』值參考 |
『可用支付工具查詢』回傳欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| code | string | 交易回傳碼(B200或B500或100) | |
| msg | string | 回傳訊息 | |
| content | string | 支付方式清單(狀態B200才有) |
其他關聯欄位說明
關聯欄位
『商品項目』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| id | string | 商品編號 | 必填 |
| name | string | 商品名稱 | 必填 |
| cost | integer | 商品單價 | 必填 |
| amount | integer | 商品數量 | 必填 |
| total | integer | 商品小計 | 必填 |
| image_url | string | 商品圖片連結(僅LINEPay線上使用) |
『無卡分期消費者資訊』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| ip | string | 消費者登入ip | |
| user_id | string | 該消費者在特店中註冊帳號名稱 | |
| user_name | string | 消費者姓名 | |
| user_real_name | string | 消費者真實姓名 | |
| user_address_post_zone | string | 消費者地址郵遞區號 | |
| user_address | string | 消費者地址 | |
| user_sn_type | string | 證號類型 | 『證號類型』值參考 |
| user_sn | string | 消費者身份證字號/統一證號/護照號碼 | |
| issue_date | string | 消費者發證(身分證)日期(YYYYMMDD) | |
| issue_place | string | 消費者領補換(身分證)地點 10001:北縣,10002:宜縣,10003:桃縣,10004:竹縣,10005:苗縣,10006:中縣,10007:彰縣,10008:投縣,10009:雲縣,10010:嘉縣,10011:南縣,10012:高縣,10013:屏縣,10014:東縣,10015:花縣,10016:澎縣,10017:基市,10018:竹市,10020:嘉市,09007:連江,09020:金門,63000:北市,64000:高市,65000:新北市,66000:中市,67000:南市,68000:桃市 | |
| issue_type | string | 消費者領補換(身分證件)類型 0:領補發,1:初發,2:補發,3:換發 | |
| user_phone_code | string | 消費者家用電話(白天電話):國碼(預設886) | |
| user_phone_area_code | string | 消費者家用電話(白天電話):區碼 | |
| user_phone | string | 消費者家用電話(白天電話) | |
| user_phone_ext | string | 消費者家用電話(白天電話):分機 | |
| user_cellphone_code | string | 消費者行動電話國碼(預設886) | |
| user_cellphone | string | 消費者行動電話 | |
| user_email | string | 消費者 E-Mail | |
| user_birthday | string | 消費者生日(格式為 YYYYMMDD,如 20090916) | |
| residence_address_post_zone | string | 消費者戶籍地址:郵遞區號 | |
| residence_address | string | 消費者戶籍地址:路街巷弄號樓室 | |
| residence_phone_area_code | string | 消費者戶籍電話:區碼 | |
| residence_phone | string | 消費者戶籍電話:號碼 | |
| residence_phone_ext | string | 消費者戶籍電話:分機 | |
| bank_code | string | 消費者銀行帳戶:銀行代碼 | |
| bank_branch_code | string | 消費者銀行帳戶: 分行代碼 | |
| bank_account_name | string | 消費者銀行帳戶:銀行帳戶名稱 | |
| bank_account_number | string | 消費者銀行帳戶:銀行帳號 | |
| salary_bank_code | string | 薪轉存摺銀行代碼 | |
| salary_bank_branch_code | string | 薪轉存摺分行代碼 | |
| salary_bank_account_number | string | 薪轉帳號 | |
| house_owner | string | 消費者居住房屋:擁有者 1:自有,2:配偶,3:親人,4租賃 | |
| living_years | string | 消費者居住房屋-年數 | |
| living_months | string | 消費者居住房屋-月數 | |
| mailing_address_post_zone | string | 消費者通訊地址:郵遞區號 | |
| mailing_address | string | 消費者通訊地址:路街巷弄號樓室 | |
| marital_status | string | 消費者婚姻狀況 1:單身,2:已婚,3:離婚 | |
| children | string | 消費者擁有子女數 | |
| education_level | string | 消費者教育程度 1:博士,2:研究所,3:大學/大專,4:高中職,5:國中/國小 | |
| organization_type | string | 工作組織類型 1:公司,2.營登,3:財法,4:社法,5:公職 | |
| organization_id | string | 消費者公司統一編號(營登/財法/社法) | |
| organization_name | string | 消費者公司名稱(服務單位) | |
| organization_phone_area_code | string | 消費者公司電話(服務單位電話):區碼 | |
| organization_phone | string | 消費者公司電話(服務單位電話):電話號碼 | |
| organization_phone_ext | string | 消費者公司電話(服務單位電話):分機號碼 | |
| organization_address_post_zone | string | 消費者公司(服務單位)地址:郵遞區號 | |
| organization_address | string | 消費者公司(服務單位)地址 | |
| employment_status | string | 消費者就業狀態 | |
| career | string | 消費者職務類型 | |
| subcareer | string | 消費者次要職務類型 | |
| grade | string | 消費者職等 | |
| working_years | string | 消費者工作年資:年數 | |
| working_months | string | 消費者工作年資:月數 | |
| monthly_salary | string | 消費者月薪 | |
| legal_representative_name | string | 消費者法定代理人:姓名 | |
| legal_representative_personal_id | string | 消費者法定代理人:身分證字號 | |
| legal_representative_birthday | string | 消費者法定代理人:出生日期 | |
| legal_representative_contact_address_post_zone | string | 消費者法定代理人:聯絡地址:郵遞區號 | |
| legal_representative_contact_address | string | 消費者法定代理人:聯絡地址:路街巷弄號樓 | |
| legal_representative_home_phone_area_code | string | 消費者法定代理人:住家電話:區碼 | |
| legal_representative_home_phone | string | 消費者法定代理人:住家電話:電話號碼 | |
| legal_representative_cellphone | string | 消費者法定代理人:行動電話 | |
| contact_time | string | 指定照會時間 | |
| payment_method | string | 消費者繳款方式 (帶冒號後的值) 電子帳單: 1 超商簡訊繳款: 3 | |
| creditcard_status | string | 消費者信用卡:狀態 (帶冒號後的值) 沒辦過卡: 1 無卡自停: 2 協商繳款中: 3 其他: 4 | |
| creditcard_status_remark | string | 消費者信用卡:狀態說明 | |
| customer_creditcard_bank_code | string | 消費者信用卡:發卡銀行代碼 | |
| creditcard_validdate_month | string | 消費者信用卡:有效日期:月 | |
| creditcard_validdate_year | string | 消費者信用卡:有效日期:年 | |
| contact_person_name | string | 聯絡人:中文姓名 | |
| contact_person_relationship | string | 聯絡人:關係 1配偶 2父母 3兄弟姐妹 4其他親友 5同事 6朋友 7子女 8其他 | |
| contact_person_cellphone | string | 聯絡人:行動電話 | |
| contact_person_phone_area_code | string | 聯絡人:住宅電話:區碼 | |
| contact_person_phone | string | 聯絡人:住宅電話:號碼 | |
| contact_person_phone_ext | string | 聯絡人:住宅電話:分機 | |
| contact_person_organization_phone_area_code | string | 聯絡人:公司電話:區碼 | |
| contact_person_organization_phone | string | 聯絡人:公司電話:號碼 | |
| contact_person_organization_phone_ext | string | 聯絡人:公司電話:分機 | |
| contact_person_confidentiality | string | 聯絡人:是否保密照會?(是:1,否:0) | |
| contact_person_meeting_time | string | 聯絡人:照會時間(日期時間 YYYYMMDDHHMM) | |
| contact_person2_name | string | 聯絡人2:中文姓名 | |
| contact_person2_relationship | string | 聯絡人2:關係 1配偶 2父母 3兄弟姐妹 4其他親友 5同事 6朋友 7子女 8其他 | |
| contact_person2_cellphone | string | 聯絡人2:行動電話 | |
| contact_person2_phone_area_code | string | 聯絡人2:住宅電話:區碼 | |
| contact_person2_phone | string | 聯絡人2:住宅電話:號碼 | |
| contact_person2_phone_ext | string | 聯絡人2:住宅電話:分機 | |
| contact_person2_organization_phone_area_code | string | 聯絡人2:公司電話:區碼 | |
| contact_person2_organization_phone | string | 聯絡人2:公司電話:號碼 | |
| contact_person2_organization_phone_ext | string | 聯絡人2:公司電話:分機 | |
| contact_person2_confidentiality | string | 聯絡人2:是否保密照會?(是:1,否:0) | |
| contact_person2_meeting_time | string | 聯絡人2:照會時間(日期時間 YYYYMMDDHHMM) | |
| guarantor_option | string | 連帶保人:選項 1.連帶保證人(需附保證人身分證正反面影本) 2.配偶資料僅供參考 3.法定代理人(需於法代欄位簽名) 4.商品實際使用人 | |
| guarantor_name | string | 連帶保人:姓名 | |
| guarantor_license_id | string | 連帶保人:身分證字號 | |
| guarantor_issue_date | string | 保證人發證(身分證)日期(YYYYMMDD) | |
| guarantor_issue_place | string | 保證人領補換(身分證)地點 10001:北縣,10002:宜縣,10003:桃縣,10004:竹縣,10005:苗縣,10006:中縣,10007:彰縣,10008:投縣,10009:雲縣,10010:嘉縣,10011:南縣,10012:高縣,10013:屏縣,10014:東縣,10015:花縣,10016:澎縣,10017:基市,10018:竹市,10020:嘉市,09007:連江,09020:金門,63000:北市,64000:高市,65000:新北市,66000:中市,67000:南市,68000:桃市 | |
| guarantor_issue_type | string | 保證人領補換(身分證件)類型 0:領補發,1:初發,2:補發,3:換發 | |
| guarantor_birthday | string | 連帶保人:出生日期(yyyy-mm-dd) | |
| guarantor_cellphone | string | 連帶保人:行動電話 | |
| guarantor_home_phone_area_code | string | 連帶保人:住家電話:區碼 | |
| guarantor_home_phone | string | 連帶保人:住家電話:號碼 | |
| guarantor_home_phone_ext | string | 連帶保人:分機 | |
| guarantor_relationship | string | 連帶保人:關係 1配偶 2父母 3兄弟姐妹 4其他親友 5同事 6朋友 7子女 8其他 | |
| guarantor_address_post_zone | string | 連帶保人:地址:郵遞區號 | |
| guarantor_address | string | 連帶保人:地址 | |
| guarantor_organization_id | string | 連帶保證人公司統編 | |
| guarantor_organization_name | string | 連帶保人:公司名稱 | |
| guarantor_organization_phone_area_code | string | 連帶保人:公司電話:區碼 | |
| guarantor_organization_phone | string | 連帶保人:公司電話:號碼 | |
| guarantor_organization_phone_ext | string | 連帶保人:公司電話:分機 | |
| guarantor_employment_status | string | 連帶保人:就業狀態 | |
| guarantor_career | string | 連帶保人:職務類型 | |
| guarantor_subcareer | string | 連帶保人:次要職務類型 | |
| guarantor_grade | string | 連帶保人:職等 | |
| guarantor_monthly_salary | string | 連帶保證人月薪 | |
| guarantor_working_years | string | 連帶保證人工作年資-年數 | |
| guarantor_working_months | string | 連帶保證人工作年資-月數 | |
| guarantor_meeting_time | string | 連帶保證人聯絡時間 (日期格式YYYYMMDDHHmm) | |
| guarantor_salary_bank_code | string | 連帶保證人薪轉存摺銀行代碼 | |
| guarantor_salary_bank_branch_code | string | 連帶保證人薪轉存摺分行代碼 | |
| guarantor_salary_bank_account_number | string | 連帶保證人薪轉帳號 | |
| motorcycle_license_number | string | 機車行照牌照號碼 | |
| motorcycle_factory_date | string | 機車出廠日期 | |
| motorcycle_displacement | string | 機車排氣量 | |
| motorcycle_license_date | string | 行照發證日期 | |
| dealer_note | string | 經辦商備註欄 | |
| supplier_business_type | string | 業務別代碼 AA21=原車抵押 AA22=借新還舊 AA23=它行代償 CA20=商品圓融 | |
| supplier_business_type_projects | string | 專案代碼 AA21 可用代碼為:DN45、DN46、DN47。 AA22 可用代碼為:DM44、DM45。 AA23 可用代碼為:DM66、DM67。 CA20 可用代碼為:DM41、DM42、DN48 |
『無卡分期檔案』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| id | string | 檔案索引名稱 | |
| path | string | 檔案路徑 | |
| type | string | MIME 檔案類型 | |
| description | string | 說明 |
『儲值交易項目』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| id | string | 儲值產品編號(最長限32 Bytes) | |
| name | string | 儲值商品名稱 | |
| price | string | 儲值點數 | |
| amount | string | 儲值數量 | |
| total | string | 儲值點數小計 |
『後付款送貨資訊』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| shipment_type | integer | 配送方式 | 『後付款送貨資訊』值參考 |
| company_name | string | 寄送地公司名稱 | |
| department_name | string | 寄送地部門名稱 | |
| name | string | 收貨姓名 | 必填 |
| cvs | integer | 超商類型(超商店到店必填) | 『後付款超商取貨』值參考 |
| cvs_store | string | 超商店號代碼(超商店到店必填) | |
| cvs_store_name | string | 超商店號名稱(超商店到店必填) | |
| zip_code | string | 收貨郵遞區號(純宅配必填) | |
| ship_address | string | 收貨地址(超商店到店為超商店址) | 必填 |
| tel | string | 收貨電話(超商店到店為超商電話) | 必填 |
『交易查詢』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| uid | string | Payment Hub之交易流水號 | |
| key | string | 交易驗証碼 | |
| prc | string | 主要交易回傳碼(retcode) | |
| finishtime | string | 交易完成時間(YYYYMMDDHHmmss) | |
| cardno | string | 銀行端口回傳碼 | |
| acode | string | 授權碼 | |
| card_type | 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 | 實際交易幣別 | |
| voucher_paid | array | 有償票券項目 | 每筆『有償票券項目』欄位參考 |
| voucher_free | array | 無償票券項目 | 每筆『無償票券項目』欄位參考 |
| 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 | string | 電子發票列印標題格式 | |
| 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_cloud_type | string | 電子發票開立類型-雲端發票類型 | 『雲端發票類型』值參考 |
| invoice_mobile_code | string | 當invoice_cloud_type為2時紀錄的手機條碼 | |
| invoice_tax_id | string | 當invoice_cloud_type為2時紀錄的統一編號 | |
| invoice_natural_person | string | 當invoice_cloud_type為3時紀錄的自然人憑證條碼 | |
| invoice_love_code | string | 當invoice_input_type為2時紀錄的愛心碼 | |
| invoice_b2b_title | string | 當invoice_input_type為3時紀錄的發票抬頭 | |
| invoice_b2b_id | string | 當invoice_input_type為3時紀錄的統一編號 | |
| invoice_b2b_post_zone | string | 當invoice_input_type為3時紀錄的郵遞區號 | |
| invoice_b2b_address | string | 當invoice_input_type為3時紀錄的發票地址 | |
| 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 |
『商品項目』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| id | string | 商品編號 | |
| name | string | 商品名稱 | |
| cost | string | 商品單價 | |
| amount | string | 商品數量 | |
| total | string | 商品小計 |
『交易查詢-退款資訊』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| 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) |
『退款完成回傳資訊』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| 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 |
『商品細項』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| Description | string | 商品名稱 | |
| Quantity | string | 數量 | |
| UnitPrice | string | 單價 | |
| Amount | string | 總金額 |
『電子發票折讓資訊』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| uid | string | 發生之退款交易流水號(UID) | |
| amount | integer | 電子發票折讓金額 | |
| order_detail | string | 電子發票折讓明細(JSON格式) | 『商品細項』值參考 |
『虛擬帳號回傳欄位』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| 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 |
『超商條碼繳費』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| BarCode1 | string | 繳費條碼1(格式:Code-39 barcode) | |
| BarCode2 | string | 繳費條碼2(格式:Code-39 barcode) | |
| BarCode3 | string | 繳費條碼3(格式:Code-39 barcode) | |
| LimitDate | string | 繳費有效期限,格式YYYYMMDDHHmmss |
值的定義
『交易服務類型』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 0 | integer | 尚未進行閘道交易 | |
| 1 | integer | 代收代付 | |
| 2 | integer | 特店模式 |
『證號類型』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 1 | integer | 身份證字號(預設) | |
| 2 | integer | 統一證號 | |
| 3 | integer | 護照號碼 |
『幣別類型』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| TWD | integer | 新台幣(預設) | |
| CNY | integer | 人民幣 |
『自動換匯』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 0 | integer | 關閉(預設) | |
| 1 | integer | 開啟 |
『分期類型定義』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| W | string | 每週定期扣款 | |
| F | string | 雙週定期扣款 | |
| M | string | 每月定期扣款 | |
| S | string | 每季定期扣款 | |
| H | string | 每半年定期扣款 | |
| A | string | 每一年定期扣款 | |
| O | string | 一次性扣款 |
『付款方式』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| all | string | 全部可用支付方式(預設) | |
| MobilePayAll | string | 指定下列線上行動支付方式 支付寶、Pi 拍錢包、LINEPay、微信、街口支付、悠遊付 | |
| CREDITCARD | string | 信用卡 | |
| CSTORECODE | string | 超商代碼 | |
| WEBATM | string | WEBATM | |
| E_COLLECTION | string | 虛擬帳號 | |
| UNIONPAY | string | 銀聯卡 | |
| SVC | string | 點數卡(GASH ,Imoney) | |
| ABROAD | string | 海外信用卡 | |
| ALIPAY | string | 支付寶 | |
| string | 微信支付 | ||
| DIRECTDEBIT | string | 定期定額扣款 | |
| LINEPAYON | string | LINE Pay線上付款 | |
| LINEPAYOFF | string | LINE Pay線下付款 | |
| WECHATOFF | string | 微信支付線下 | |
| APPLEPAY | string | APPLE PAY | |
| GOOGLEPAY | string | Google Pay | |
| EACH | string | eACH交易 | |
| C_INSTALLMENT | string | 信用卡分期 | |
| C_REDEEM | string | 信用卡紅利 | |
| 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 | 超商條碼繳費 | |
| IPASSMONEYON | string | 一卡通線上 | |
| IPASSMONEYOFF | string | 一卡通線下 |
『啟用快速結帳』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 0 | integer | 關閉 | |
| 1 | integer | 開啟(預設) |
『啟用電子錢包』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 0 | integer | 關閉(預設) | |
| 1 | integer | 開啟 |
『電子錢包執行類型』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 1 | integer | 電子錢包前景交易(預設) | |
| 2 | integer | 電子錢包背景交易 |
『交易類型』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 1 | string | 網路交易(預設)(消費者直接輸入支付內容) | |
| 2 | string | 實體交易 (商戶面對消費者時,由商戶輸入支付內容做消費) |
『電子發票是否開立狀態』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 0 | integer | 不開立電子發票 | |
| 1 | integer | 開立電子發票 | |
| 2 | integer | 依系統設定(預設) |
『電子發票稅率別』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 1 | integer | 應稅(預設) | |
| 2 | integer | 零稅率 | |
| 3 | integer | 免稅 |
『雲端發票類型』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 2 | integer | 手機條碼 | |
| 3 | integer | 自然人憑證條碼 | |
| 4 | integer | 以E-Mail寄送 |
『電子發票欄位異動』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 0 | integer | 可以異動(預設) | |
| 1 | integer | 不可異動 |
『含不含簡訊費』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 1 | integer | 含手續費 | |
| 0 | integer | 不含手續費(預設) |
『含不含手續費類型』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 1 | integer | 含手續費 | |
| 0 | integer | 不含手續費(預設) |
『後付款送貨資訊』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 2 | integer | 純宅配 | |
| 4 | integer | 超商店到店 |
『後付款超商取貨』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 1 | integer | 7-11 | |
| 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 |
『有償票券項目』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| product_id | string | 票券群組編號(最長限32 Bytes) | |
| serial_number | string | 票券券號(特約商店下的每一個票券群組的票券券號必須是唯一) | |
| name | string | 票券名稱 | |
| cost | integer | 票券金額 | |
| issuer | string | 發行者 | 『有價票券發行者』值參考 |
| refund_return_type | string | 退款時,票券金額是否歸還 | 『退款時票券金額是否歸還』值參考 |
『無償票券項目』欄位
| 參數名稱 | 型態 | 說明 | 必須 |
|---|---|---|---|
| product_id | string | 票券群組編號(最長限32 Bytes) | |
| serial_number | string | 票券券號(特約商店下的每一個票券群組的票券券號必須是唯一) | |
| name | string | 票券名稱 | |
| cost | integer | 票券金額 | |
| issuer | string | 發行者 | 『免費票券發行者』值參考 |
『交易類型定義』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 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 | 串流 |
『電子發票開立狀態類型』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 0 | integer | 不處理(預設) | |
| 1 | integer | 等候處理中, | |
| 2 | integer | 發票開立成功 | |
| 3 | integer | 發票處理失敗 | |
| 4 | integer | 作癈 | |
| 5 | integer | 系統或特約商店發票號碼設定不正確 | |
| 6 | integer | 折讓 |
『電子發票紙本列印標題類型』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 1 | integer | 文字 | |
| 2 | integer | 圖形(圖片網址) |
『電子發票稅率別』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 1 | integer | 應稅(預設) | |
| 2 | integer | 零稅率 | |
| 3 | integer | 免稅 |
『電子發票開立類型』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 1 | integer | 雲端發票 | |
| 2 | integer | 發票捐贈 | |
| 3 | integer | 實體發票 | 1.重要提示,若選擇此模式,商戶需要自行列印實體發票交付給消費者,系統不會寄送mail通知與中獎後也不會通知給消費者。電子發票列印格式,請參考國稅局頒布標準。 2.使用paypage交易與開立發票同時進行時,絕對不可以使用此模式,因為系統會根據消費者在paypage畫面上的選擇,開立捐贈或雲端載具 |
『紅利資訊類型』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 1 | integer | 全額 | |
| 2 | 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 | 超商條碼繳費 | |
| IPASSMONEYON | string | 一卡通線上 | |
| IPASSMONEYOFF | string | 一卡通線下 |
『信用卡別類型』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 0 | integer | 無法辨識或支付方式為非信用卡類 | |
| 1 | integer | VISA | |
| 2 | integer | MasterCard | |
| 3 | integer | JCB | |
| 4 | integer | AMEX |
『電子發票退款時使用作廢或折讓』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 4 | integer | 作廢或作廢重開 | 預設 |
| 6 | integer | 折讓 |
『電子發票列印類型』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 0 | integer | 不列印 自行處置 | |
| 1 | integer | 列印 電子發票 + 商品明細 | |
| 2 | integer | 只印電子發票 | |
| 3 | integer | 只印商品明細 |
『電子發票列印設備』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 0 | integer | 自行處理 | |
| 1 | integer | SUNMI V2 PRO |
『是否為經銷商代收費模式』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 1 | integer | 是經銷商代收費模式 | |
| 0 | integer | 不是經銷商代收費模式 |
『信用卡授權請款模式類型』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 0 | string | 自行請款 | |
| 1 | string | 自動請款(預設) |
『電子錢包執行狀態碼』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 100 | string | 資料不正確 | |
| 400 | string | 系統錯誤 | |
| B200 | string | 執行成功 | |
| B500 | string | 執行失敗 |
『經銷商代收款核銷服務提供方式』值內容
| 值 | 型態 | 說明 | 備註 |
|---|---|---|---|
| 1 | integer | 貨運 | |
| 2 | integer | 課程 | |
| 3 | integer | 票券 | |
| 4 | integer | 講座活動 | |
| 5 | integer | 數位商品 | |
| 6 | integer | 點數捐贈 | |
| 7 | integer | 個人贊助 |
title: MYPAY APP 技術串接手冊(包含MYPAY TAP APP)
language_tabs: # must be one of https://git.io/vQNgJ
- java
- html
toc_footers:
search: true
MYPAY APP 技術串接手冊(包含MYPAY TAP APP)
名詞定義
| 名詞 | 定義 | 備注 |
|---|---|---|
| 串接方POS系統 | 串接方所開發的POS系統,可能是Web POS或App | |
| 串接方App | 串接方的App,也就是呼叫使用MYPAY APP的App | |
| 卡機 | 刷卡機的簡稱,指可以安裝MYPAY APP的設備,但在MYPAY TAP APP的情況下,通常指一般有NFC功能的設備,而非EMV裝置 | |
| 藍牙裝置 | 支援藍牙傳輸資料的裝置 | |
| MYPAY Server | 提供MYPAY金流服務的Server | |
| MYPAY APP | 提供給串接方App呼叫進行交易或查詢的App | 請參考MYPAY與MPAY TAP的差異 |
| MYPAY TAP APP | 提供給串接方App呼叫進行交易或查詢的App | 請參考MYPAY與MPAY TAP的差異 |
| MyPayCommon | 提供給串接方App進行串接MYPAY APP使用的AAR Lib | 下載連結為MyPayCommon |
| AppRequest & AppResponse | 串接方自行定義的request和response類別,可將其轉換為JSON Object string放入或取出ActionDetails.data,用來跟MYPAY APP溝通 | Lib 0.0.45 |
| Cross Action | 為透過MyPayCommon呼叫MYPAY APP的Action類別,開頭為ACTION_ | 此類別會有流程的處理,如掃碼、感應卡片...等,並在返回串接方App時傳送回傳值 |
| Cross Page | 為透過MyPayCommon呼叫MYPAY APP的Action類別,開頭為PAGE_ | 此類別不會有流程的處理,只是單純的跳頁,使用者點下返回時,只會回到上一頁(串接方App原本發動Cross Page的那個頁面),不會有任何的回傳值 |
MYPAY與MPAY TAP的差異
| MYPAY | MYPAY TAP | 備注 | |
|---|---|---|---|
| 支援最低Android版本 | 7以上 | 9以上 | |
| 支援GMS | 非必要 | 必要 | GMS為Google Mobile Services的簡稱,詳情請參考GMS |
| 支援NFC | 非必要 | 必要 | |
| 為EMV設備 | 是 | 否 | |
| 支援的Action | 請參考MYPAY支援的Action | 請參考MYPAY TAP支援的Action | |
| 目前支援的商米設備 | P2 PRO | V2s V3 V3 MIX D3 MINI | 其它不在列表中的設備不保證可以串接成功 |
| 目前支援的iMin設備 | Swift 2 Pro | 其它不在列表中的設備不保證可以串接成功 | |
| 串接的PACKAGE_NAME | 測試環境︰ cc.usecase.mypay 正式環境︰ tw.com.mypay | 測試環境︰ tw.com.mypay.tap.dev 正式環境︰ tw.com.mypay.tap | |
| 串接的TARGET_ACTIVITY_NAME | tw.com.mypay.MainActivity | tw.com.mypay.MainActivity |
支援的Action說明
| 項次 | 說明 | 備註 |
|---|---|---|
| 1 | 請參考MYPAY支援的Action | |
| 2 | 請參考MYPAY TAP支援的Action |
MYPAY支援的Action
| Action名稱與對應的值 | Action的類別 | 備註 |
|---|---|---|
| 請參考共同支援的Action |
MYPAY TAP支援的Action
| Action名稱與對應的值 | Action的類別 | 備註 |
|---|---|---|
| 請參考共同支援的Action | 不支援ACTION_SEND_TRANSACTION中的PAY_MODE_ID_CREDIT_CARD參數,請使用ACTION_TAP進行信用卡交易 | |
| ACTION_TAP tw.com.mypay.action.TAP | Cross Action | MYPAY TAP APP的信用卡交易請使用此Action,請勿使用ACTION_SEND_TRANSACTION,Lib 0.1.3 |
| ACTION_TAP_REFUND tw.com.mypay.action.TAP_REFUND | Cross Action | MYPAY TAP APP的信用卡退款請使用此Action,請勿使用ACTION_REFUND,Lib 0.3.3 |
| ACTION_TAP_INIT tw.com.mypay.action.TAP_INIT | Cross Action | 可在信用卡交易或退款之前呼叫,以減少在交易時等待初始化的時間,Lib 0.3.6 |
共同支援的Action
| Action名稱與對應的值 | Action的類別 | 備註 |
|---|---|---|
| ACTION_SEND_TRANSACTION tw.com.mypay.action.SEND_TRANSACTION | Cross Action | Lib 0.0.45 |
| ACTION_QUERY_TRANSACTION tw.com.mypay.action.QUERY_TRANSACTION | Cross Action | Lib 0.0.45 |
| ACTION_REFUND tw.com.mypay.action.REFUND | Cross Action | Lib 0.0.45 |
| ACTION_PRINT tw.com.mypay.action.PRINT | Cross Action | Lib 0.0.45 |
| ACTION_SCAN_CODE tw.com.mypay.action.SCAN_CODE | Cross Action | Lib 0.1.5 |
| ACTION_GET_SUPPORTED_PAY_MODES tw.com.mypay.action.GET_SUPPORTED_PAY_MODES | Cross Action | Lib 0.2.5 |
| ACTION_GET_SUPPORTED_ACTUAL_PAY_MODES tw.com.mypay.action.GET_SUPPORTED_ACTUAL_PAY_MODES | Cross Action | Lib 0.3.0 |
| ACTION_QUERY_COUPON_CODE tw.com.mypay.action.QUERY_COUPON_CODE | Cross Action | Lib 0.2.4 |
| ACTION_CREATE_INVOICE tw.com.mypay.action.CREATE_INVOICE | Cross Action | Lib 0.3.4 |
| PAGE_MYPAY_ORDER_LIST tw.com.mypay.page.MYPAY_ORDER_LIST | Cross Page | Lib 0.1.8 |
| PAGE_MYPAY_FOOD_ORDER_LIST tw.com.mypay.page.MYPAY_FOOD_ORDER_LIST | Cross Page | Lib 0.1.9 |
| PAGE_MYPAY_INVOICE_MANAGEMENT tw.com.mypay.page.MYPAY_INVOICE_MANAGEMENT | Cross Page | Lib 0.1.9 |
| PAGE_MYPAY_RECEIPT_MANAGEMENT tw.com.mypay.page.MYPAY_RECEIPT_MANAGEMENT | Cross Page | Lib 0.1.9 |
| PAGE_MYPAY_PRINTER_SETTINGS tw.com.mypay.page.MYPAY_PRINTER_SETTINGS | Cross Page | Lib 0.1.9 |
| PAGE_MYPAY_URL_SETTINGS tw.com.mypay.page.MYPAY_URL_SETTINGS | Cross Page | Lib 0.1.9 |
| PAGE_MYPAY_SETTLEMENT_REPORT tw.com.mypay.page.MYPAY_SETTLEMENT_REPORT | Cross Page | Lib 0.2.7 |
| PAGE_MYPAY_ACTUAL_PAY_MODE_SETTINGS tw.com.mypay.page.MYPAY_ACTUAL_PAY_MODE_SETTINGS | Cross Page | Lib 0.3.0 |
| PAGE_MYPAY_ORDER_DETAILS tw.com.mypay.page.MYPAY_ORDER_DETAILS | Cross Page | Lib 0.3.2 |
| ACTION_39_BUY_LOGIN tw.com.mypay.buy39.action.LOGIN | Cross Action | Lib 0.0.56 |
| ACTION_39_BUY_VALIDATE_APP_TOKEN tw.com.mypay.buy39.action.VALIDATE_APP_TOKEN | Cross Action | Lib 0.0.56 |
串接準備
在串接方App專案下的app/libs放入MyPayCommon_vX.X.X_release.aar (X.X.X為版本號,請使用最新版的AAR),並於app/build.gradle中加入
android {
...
repositories {
flatDir {
dirs 'libs'
}
}
...
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation(name:'MyPayCommon_vX.X.X_release', ext:'aar')
...
}若串接方App須打包為release app時,請於app/proguard-rules.pro中加入
-keep class tw.com.mypay.common.** { *; }決定要呼叫的MYPAY APP或MYPAY TAP APP是測試還是正式的版本
| PACKAGE_NAME | TARGET_ACTIVITY_NAME | 環境 |
|---|---|---|
| cc.usecase.mypay | tw.com.mypay.MainActivity | MYPAY APP測試 |
| tw.com.mypay | tw.com.mypay.MainActivity | MYPAY APP正式 |
| tw.com.mypay.tap.dev | tw.com.mypay.MainActivity | MYPAY TAP APP測試 |
| tw.com.mypay.tap | tw.com.mypay.MainActivity | MYPAY TAP APP正式 |
支援的串接方式
串接的方式可分為兩類︰裝置外部與裝置內部。
- 裝置外部︰表示串接方的程式在裝置的外部,如網路串接刷卡機模式與藍牙模式。
- 裝置內部︰表示串接方的程式在裝置的內部,如Cross App模式與瀏覽器模式。
網路串接刷卡機模式
注意︰
- 此為透過API呼叫MYPAY Server的方式串接MYPAY APP,詳情請參考︰網路串接刷卡機設計概要。
- Android 10以上的裝置,此串接方式必須在開啟MYPAY APP畫面時才能使用(系統限制)。
藍牙模式 (點此跳到)
注意︰
- 目前只提供Android串接方式的範例,若使用其它程式語言可能會有無法串接的問題。
- MYPAY APP中的藍牙傳輸設定裡的掃碼功能(v4.0.6),必須是使用此串接模式才可以正常將資料傳到接收方的應用中,無法使用其它方式接收此資料。
Cross App模式 (點此跳到)
Lib檔下載連結為MyPayCommon
瀏覽器模式 (點此跳到)
Cross App交易動作
使用MyPayCommon中的tw.com.mypay.common.ActionDetails傳入所需的資料,再透過Intent傳送到MYPAY APP ,ActionDetails為一共用類別,串接方傳送請求時使用ActionDetails傳送,接收回應時也是使用相同的ActionDetails,其不同在於ActionDetails中的data在傳送請求時是request資料,而接收回應時是response資料,以下為各動作的範例︰
進行交易
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private ActionDetails getTransactionActionDetails(Object appRequest) {
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_SEND_TRANSACTION);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
return actionDetails;
}
private void sendCreditCardTransaction() { // 信用卡交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setPayModeId(Constant.PAY_MODE_ID_CREDIT_CARD);
ActionDetails actionDetails = getTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendOfflineTransaction() { // 所有線下交易,掃碼收款
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setPayModeId(Constant.PAY_MODE_ID_OFFLINE_ALL);
ActionDetails actionDetails = getTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendScanQrCodeTransaction() { // 產生QrCode,線上
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setPayModeId(Constant.PAY_MODE_ID_LINE_PAY); // LINE Pay線上
//appRequest.setPayModeId(Constant.PAY_MODE_ID_PI); // Pi 拍錢包線上
//appRequest.setPayModeId(Constant.PAY_MODE_ID_JKO); // 街口支付線上
//appRequest.setPayModeId(Constant.PAY_MODE_ID_WECHAT); // 微信支付線上
//appRequest.setPayModeId(Constant.PAY_MODE_ID_ALIPAY); // 支付寶線上
//appRequest.setPayModeId(Constant.PAY_MODE_ID_EASY_WALLET); // 悠遊付線上
ActionDetails actionDetails = getTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行交易查詢
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void queryTransaction() { // 交易查詢
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_QUERY_TRANSACTION);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行退款
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void refund() { // 退款
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setInvoiceState(Constant.INVOICE_STATE_VOID); // 作廢或作廢重開
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_REFUND);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}Cross App TAP動作(只有MYPAY TAP APP支援)
進行初始化
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void tapInit() { // TAP初始化
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_TAP_INIT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行交易
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void sendTapTransaction() { // TAP交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_TAP);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行退款
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void tapRefund() { // TAP退款
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_TAP_REFUND);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}Cross App一卡通動作(Lib 0.2.0)
進行詢卡
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void queryCard() { // 詢卡
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setType(1); // 快速詢卡
//appRequest.setType(2); // 離線詢卡
//appRequest.setType(3); // 連線詢卡
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_I_PASS_QUERY_CARD);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行扣值交易
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void redeem() { // 扣值交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setType(1);
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_I_PASS_REDEEM);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行現金加值交易
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void reload() { // 現金加值交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setType(3);
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_I_PASS_RELOAD);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行取消交易
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void cancelTransaction() { // 取消交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setType(2); // 取消扣值交易
//appRequest.setType(4); // 取消現金加值交易
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_I_PASS_CANCEL);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行退貨加值交易
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void refund() { // 退貨加值交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setType(5);
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_I_PASS_REFUND);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行結班
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void closeBatch() { // 結班
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_I_PASS_CLOSE_BATCH);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}Cross App其它動作(Lib 0.1.5)
進行列印(直接列印,不處理交易資料)
注意︰
此動作為單純將串接方的資料排列處理並列印成MYPAY制式的單據,不會產生交易與發票相關的資料,只是將MYPAY APP當作印表機使用。
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void print() { // 列印
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setPrintMode(Constant.PRINT_MODE_INVOICE_AND_DETAILS); // 列印發票加明細
//appRequest.setPrintMode(Constant.PRINT_MODE_INVOICE); // 列印發票
//appRequest.setPrintMode(Constant.PRINT_MODE_DETAILS); // 列印明細
//appRequest.setPrintMode(Constant.PRINT_MODE_CREDIT_CARD_RECEIPT); // 重印簽單
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_PRINT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行掃碼回傳
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void scanCode() { // 掃碼回傳
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_SCAN_CODE);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行查詢合作夥伴折扣碼
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void queryCouponCode() { // 查詢合作夥伴折扣碼
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_QUERY_COUPON_CODE);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行取得特店支援之支付方式
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void getSupportedPayModes() { // 取得特店支援之支付方式
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_GET_SUPPORTED_PAY_MODES);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行取得自行收款設定
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void getSupportedPayModes() { // 取得特店支援之支付方式
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_GET_SUPPORTED_ACTUAL_PAY_MODES);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行後開立發票
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void createInvoice() { // 後開立發票
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_CREATE_INVOICE);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}MYPAY頁面(Lib 0.1.8)
進入金流訂單列表頁
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void gotoMyPayOrderListPage() { // 進入金流訂單列表頁
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.PAGE_MYPAY_ORDER_LIST);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
}進入點餐單列表頁
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void gotoMyPayFoodOrderListPage() { // 進入點餐單列表頁
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.PAGE_MYPAY_FOOD_ORDER_LIST);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
}進入發票管理頁
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void gotoMyPayInvoiceManagementPage() { // 進入發票管理頁
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.PAGE_MYPAY_INVOICE_MANAGEMENT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
}進入收據管理頁
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void gotoMyPayReceiptManagementPage() { // 進入收據管理頁
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.PAGE_MYPAY_RECEIPT_MANAGEMENT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
}進入印表機設定頁
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void gotoMyPayPrinterSettingsPage() { // 進入印表機設定頁
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.PAGE_MYPAY_PRINTER_SETTINGS);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
}進入交易回傳設定頁
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void gotoMyPayUrlSettingsPage() { // 進入交易回傳設定頁
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.PAGE_MYPAY_URL_SETTINGS);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
}進入結帳報表頁
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void gotoMyPaySettlementReportPage() { // 進入結帳報表頁
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.PAGE_MYPAY_SETTLEMENT_REPORT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
}進入金流訂單明細頁
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void gotoMyPayOrderDetailsPage() { // 進入金流訂單明細頁
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.PAGE_MYPAY_ORDER_DETAILS);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
}進入裝置設定頁
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void gotoMyPayDeviceSettingsPage() { // 進入裝置設定頁
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.PAGE_MYPAY_DEVICE_SETTINGS);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
}進入會員API設定頁
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void gotoMyPayMemberApiSettingsPage() { // 進入會員API設定頁
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.PAGE_MYPAY_MEMBER_API_SETTINGS);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
}進入會員累扣點頁
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void gotoMyPayMemberCardPointsPage() { // 進入會員累扣點頁
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.PAGE_MYPAY_MEMBER_CARD_POINTS);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
}進入使用優惠券頁
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void gotoMyPayRedeemVoucherPage() { // 進入使用優惠券頁
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.PAGE_MYPAY_REDEEM_VOUCHER);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
}39Buy動作(Lib 0.0.56)
進行登入
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void login() { // 登入
YourAppRequest appRequest = getAppRequest(); // 你的app request
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_LOGIN);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行登出
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void logout() { // 登出
YourAppRequest appRequest = getAppRequest(); // 你的app request
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_LOGOUT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行驗證appToken
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void validateAppToken() { // 驗證appToken
YourAppRequest appRequest = getAppRequest(); // 你的app request
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_VALIDATE_APP_TOKEN);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行新增產品分類
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void addProductLevel() { // 新增產品分類
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_ADD_PRODUCT_LEVEL);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行修改產品分類
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void editProductLevel() { // 修改產品分類
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_EDIT_PRODUCT_LEVEL);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行產品分類列表查詢
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void queryProductLevel() { // 產品分類列表查詢
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_QUERY_PRODUCT_LEVEL);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行產品分類明細查詢
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void queryProductLevelDetails() { // 產品分類明細查詢
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_QUERY_PRODUCT_LEVEL_DETAILS);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行產品分類關聯查詢
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void queryProductLevelRelation() { // 產品分類關聯查詢
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_QUERY_PRODUCT_LEVEL_RELATION);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行產品分類關聯更新
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void updateProductLevelRelation() { // 產品分類關聯更新
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_UPDATE_PRODUCT_LEVEL_RELATION);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行產品列表查詢
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void queryProduct() { // 產品列表查詢
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_QUERY_PRODUCT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行產品明細查詢
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void queryProductDetails() { // 產品明細查詢
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_QUERY_PRODUCT_DETAILS);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行訂單列表查詢
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void queryOrder() { // 訂單列表查詢
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_QUERY_ORDER);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行訂單明細查詢
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void queryOrderDetails() { // 訂單明細查詢
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_QUERY_ORDER_DETAILS);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行新增一般產品
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void addGeneralProduct() { // 新增一般產品
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_ADD_GENERAL_PRODUCT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行修改一般產品
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void editGeneralProduct() { // 修改一般產品
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_EDIT_GENERAL_PRODUCT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行新增捐款產品
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void addDonationProduct() { // 新增捐款產品
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_ADD_DONATION_PRODUCT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行修改捐款產品
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void editDonationProduct() { // 修改捐款產品
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_EDIT_DONATION_PRODUCT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行新增一碼付產品
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void addQuickPayProduct() { // 新增一碼付產品
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_ADD_QUICK_PAY_PRODUCT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行修改一碼付產品
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void editQuickPayProduct() { // 修改一碼付產品
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_EDIT_QUICK_PAY_PRODUCT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行新增點燈產品
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void addLightProduct() { // 新增點燈產品
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_ADD_LIGHT_PRODUCT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行修改點燈產品
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void editLightProduct() { // 修改點燈產品
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_EDIT_LIGHT_PRODUCT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行新增超渡產品
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void addReleaseProduct() { // 新增超渡產品
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_ADD_RELEASE_PRODUCT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行修改超渡產品
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private void editReleaseProduct() { // 修改超渡產品
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setAppToken(getAppToken());
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_EDIT_RELEASE_PRODUCT);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行一般交易
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private ActionDetails getGeneralTransactionActionDetails(Object appRequest) {
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_SEND_GENERAL_TRANSACTION);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
return actionDetails;
}
private void sendCreditCardGeneralTransaction() { // 信用卡交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_CREDIT_CARD);
ActionDetails actionDetails = getGeneralTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendOfflineGeneralTransaction() { // 所有線下交易,掃碼收款
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_OFFLINE_ALL);
ActionDetails actionDetails = getGeneralTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendScanQrCodeGeneralTransaction() { // 產生QrCode,線上
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_LINE_PAY); // LINE Pay線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_PI); // Pi 拍錢包線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_JKO); // 街口支付線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_WECHAT); // 微信支付線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_ALIPAY); // 支付寶線上
ActionDetails actionDetails = getGeneralTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendCashGeneralTransaction() { // 現金交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_CASH);
ActionDetails actionDetails = getGeneralTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行捐款交易
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private ActionDetails getDonationTransactionActionDetails(Object appRequest) {
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_SEND_DONATION_TRANSACTION);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
return actionDetails;
}
private void sendCreditCardDonationTransaction() { // 信用卡交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_CREDIT_CARD);
ActionDetails actionDetails = getDonationTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendOfflineDonationTransaction() { // 所有線下交易,掃碼收款
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_OFFLINE_ALL);
ActionDetails actionDetails = getDonationTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendScanQrCodeDonationTransaction() { // 產生QrCode,線上
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_LINE_PAY); // LINE Pay線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_PI); // Pi 拍錢包線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_JKO); // 街口支付線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_WECHAT); // 微信支付線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_ALIPAY); // 支付寶線上
ActionDetails actionDetails = getDonationTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendCashDonationTransaction() { // 現金交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_CASH);
ActionDetails actionDetails = getDonationTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行一碼付交易
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private ActionDetails getQuickPayTransactionActionDetails(Object appRequest) {
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_SEND_QUICK_PAY_TRANSACTION);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
return actionDetails;
}
private void sendCreditCardQuickPayTransaction() { // 信用卡交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_CREDIT_CARD);
ActionDetails actionDetails = getQuickPayTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendOfflineQuickPayTransaction() { // 所有線下交易,掃碼收款
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_OFFLINE_ALL);
ActionDetails actionDetails = getQuickPayTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendScanQrCodeQuickPayTransaction() { // 產生QrCode,線上
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_LINE_PAY); // LINE Pay線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_PI); // Pi 拍錢包線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_JKO); // 街口支付線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_WECHAT); // 微信支付線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_ALIPAY); // 支付寶線上
ActionDetails actionDetails = getQuickPayTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendCashQuickPayTransaction() { // 現金交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_CASH);
ActionDetails actionDetails = getQuickPayTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行點燈交易
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private ActionDetails getLightTransactionActionDetails(Object appRequest) {
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_SEND_LIGHT_TRANSACTION);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
return actionDetails;
}
private void sendCreditCardLightTransaction() { // 信用卡交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_CREDIT_CARD);
ActionDetails actionDetails = getLightTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendOfflineLightTransaction() { // 所有線下交易,掃碼收款
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_OFFLINE_ALL);
ActionDetails actionDetails = getLightTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendScanQrCodeLightTransaction() { // 產生QrCode,線上
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_LINE_PAY); // LINE Pay線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_PI); // Pi 拍錢包線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_JKO); // 街口支付線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_WECHAT); // 微信支付線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_ALIPAY); // 支付寶線上
ActionDetails actionDetails = getLightTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendCashLightTransaction() { // 現金交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_CASH);
ActionDetails actionDetails = getLightTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}進行超渡交易
...
import tw.com.mypay.common.ActionDetails;
import tw.com.mypay.common.Constant;
...
public class YourActivity extends AppCompatActivity {
...
private ActionDetails getReleaseTransactionActionDetails(Object appRequest) {
ActionDetails actionDetails = new ActionDetails();
actionDetails.setAction(Constant.ACTION_39_BUY_SEND_RELEASE_TRANSACTION);
actionDetails.setData(getAppRequestJsonString(appRequest)); // 取得app request的JSON string
return actionDetails;
}
private void sendCreditCardReleaseTransaction() { // 信用卡交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_CREDIT_CARD);
ActionDetails actionDetails = getReleaseTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendOfflineReleaseTransaction() { // 所有線下交易,掃碼收款
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_OFFLINE_ALL);
ActionDetails actionDetails = getReleaseTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendScanQrCodeReleaseTransaction() { // 產生QrCode,線上
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_LINE_PAY); // LINE Pay線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_PI); // Pi 拍錢包線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_JKO); // 街口支付線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_WECHAT); // 微信支付線上
//appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_ALIPAY); // 支付寶線上
ActionDetails actionDetails = getReleaseTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
private void sendCashReleaseTransaction() { // 現金交易
YourAppRequest appRequest = getAppRequest(); // 你的app request
...
// TODO 設定appRequest的參數
...
appRequest.setDesignatePayMode(Constant.BUY_39_PAY_MODE_ID_CASH);
ActionDetails actionDetails = getReleaseTransactionActionDetails(appRequest);
Intent intent = new Intent();
intent.putExtra(Constant.INTENT_EXTRA_KEY_REQUEST_ACTION_DETAILS, actionDetails);
intent.setClassName(PACKAGE_NAME, TARGET_ACTIVITY_NAME);
this.startActivityForResult(intent, yourRequestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((yourRequestCode == requestCode) && (data != null)) {
ActionDetails actionDetails = data.getParcelableExtra(Constant.INTENT_EXTRA_KEY_RESPONSE_ACTION_DETAILS);
YourAppResponse appResponse = (YourAppResponse) getAppResponse(actionDetails.getData()); // 轉換為你的app response
...
// 處理actionDetails與appResponse的資料
...
}
}
}藍牙呼叫MYPAY APP動作(APP v3.9.0)
使用ExternalActionDetails傳入所需的資料(須加密),再透過藍牙傳送到MYPAY APP。
注意︰
- 串接方使用的裝置和安裝MYPAY APP的設備都必須支援藍牙功能。
- 串接方使用的裝置需要先和安裝MYPAY APP的設備配對藍牙。
- 登入MYPAY APP後,在藍牙傳輸設定頁面中確認藍牙串接ID,並加入串接方的程式中,接著開啟藍牙Server服務。
- 請使用RFCOMM BluetoothSocket的連接方式,可參考(https://github.com/android/connectivity-samples)。
- 之後再進行加密資料的傳送。
ExternalActionDetails說明
ExternalActionDetails為一個JSON Object的string,格式如下︰ "{ "storeUid": "", "action": "", "data": "" }"
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | storeUid | 特店代號 | string | |
| 2 | action | 加密後的動作 | string | 請參考ActionDetails說明中使用的action |
| 3 | data | 加密後的資料 | string | 請參考ActionDetails說明中使用的appRequest |
ExternalActionDetails中action與data的加密方式
private String encrypt(String input, byte[] key, byte[] iv) {
byte[] data = aes(input.getBytes(UTF_8), key, iv); // AES-256-CBC-PKCS7
return base64(iv, data); // 將IV放在加密資料前面(IV + data),再整個轉成Base64的字串
}
private void sendByBluetooth(Object appRequest) {
String storeUid = getYourStoreUid(); // 你的特店代號
String storeKey = getYourStoreKey(); // 你的特店金鑰
String encryptedAction = encrypt(getAction(), storeKey.getBytes(), getRandomIv(16));
String encryptedData = encrypt(getAppRequestJsonString(appRequest), storeKey.getBytes(), getRandomIv(16));
ExternalActionDetails actionDetails = new ExternalActionDetails();
actionDetails.setStoreUid(storeUid);
actionDetails.setAction(encryptedAction);
actionDetails.setData(encryptedData);
String requestString = getJsonString(actionDetails);
// 透過藍牙傳送給MYPAY APP
}藍牙掃碼傳輸說明
必須先串接藍牙模式,再透過MYPAY APP -> 藍牙傳輸設定頁面 -> 掃碼,將掃描的資料透過藍牙傳輸到串接方的應用(無加密)。
注意︰
- 串接方使用的裝置和安裝MYPAY APP的設備都必須支援藍牙功能。
- 串接方使用的裝置需要先和安裝MYPAY APP的設備配對藍牙。
- 登入MYPAY APP後,在藍牙傳輸設定頁面中確認藍牙串接ID,並加入串接方的程式中,接著開啟藍牙Server服務。
- 請使用RFCOMM BluetoothSocket的連接方式,可參考(https://github.com/android/connectivity-samples)。 串接方應用需自行處理接收資料的流程。
瀏覽器呼叫MYPAY APP動作(APP v3.9.1)
使用ExternalActionDetails傳入所需的資料(須加密),再透過傳送Intent到MYPAY APP。
注意︰
- 載入串接方Web程式的瀏覽器必須和安裝的MYPAY APP在同一台設備中。
- 登入MYPAY APP後,之後再由串接方Web程式進行加密資料的傳送。
ExternalActionDetails說明
ExternalActionDetails為一個JSON Object的string,格式如下︰ "{ "storeUid": "", "action": "", "data": "" }"
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | storeUid | 特店代號 | string | |
| 2 | action | 加密後的動作 | string | 請參考ActionDetails說明中使用的action |
| 3 | data | 加密後的資料 | string | 請參考ActionDetails說明中使用的appRequest |
ExternalActionDetails中action與data的加密方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="send">Send</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<script>
function encrypt(input, key, iv) {
const bufferKey = CryptoJS.enc.Utf8.parse(key);
const bufferIv = CryptoJS.enc.Utf8.parse(iv
? iv
: CryptoJS.SHA256(
`${key}${Date.now()}`
.split('')
.sort(() => Math.random() - 0.5)
.join()
).toString(CryptoJS.enc.Hex)
.slice(0, 16)
);
const encrypted = CryptoJS.AES.encrypt(
input,
bufferKey,
{
iv: bufferIv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
return bufferIv
.concat(CryptoJS.enc.Base64.parse(encrypted.toString()))
.toString(CryptoJS.enc.Base64);
}
const sendButton = document.querySelector('#send');
const packageName = 'target app packageName';
const key = 'your store key';
const action = 'your action';
const appRequest = 'your app request';
const iv = 'your iv';
sendButton.addEventListener('click', sendToMyPayApp);
function sendToMyPayApp() {
const actionDetails = {
"storeUid": "your store uid",
"action": encrypt(action, key, iv),
"data": encrypt(appRequest, key, iv)
}
const query = JSON.stringify(actionDetails);
const intent = `intent://mypay?data=${encodeURIComponent(query)}:#Intent;scheme=mypay;action=android.intent.action.SEND;category=android.intent.category.DEFAULT;package=${packageName};end`;
window.location.href = intent;
}
</script>
</body>
</html>ActionDetails說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | version | MyPayCommon Lib的版本號 | string | 當串接方送出時為串接方使用的Lib版本號,由MYPAY APP回應時為MYPAY APP目前使用的Lib版本號(為當前最新的版本),可用來比對版本差異 |
| 2 | action | 進行的動作 | string | 必要,請參考支援的Action說明 |
| 3 | data | AppRequest或AppResponse的資料 | string | 必要,其內容值都必須為合法的JSON Object { ... },請參考以下對應的說明 |
串接方App在送出ActionDetails前可使用以下程式將所有參數印出,以確定送出之參數符合預期。 Log.d(TAG, "actionDetails: " + yourActionDetails);
ActionDetails做為AppRequest使用時
必須將你的AppRequest轉換為JSON Object的string
進行交易
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | payModeId | 交易模式代號︰ 1=信用卡 10=支付寶線上 13=微信支付線上 15=LINE Pay線上 27=Pi 拍錢包線上 31=街口支付線上 37=現金交易 38=悠遊付線上 52=全盈支付線上 56=全支付線上 98=所有線下交易 | string | 必要 |
| 3 | itemList | 商品列表 | list | 必要,請參考商品列表欄位說明 |
| 4 | currency | 交易幣別︰ TWD=新台幣 CNY=人民幣 | string | 必要 |
| 5 | ip | 呼叫端IP | string | 必要 |
| 6 | customer | 消費者資料 | object | 非必要,請參考消費者資料欄位說明 |
| 7 | invoice | 發票資料 | object | 非必要,請參考發票資料欄位說明 |
| 8 | echo | echo資料 | object | 非必要,請參考echo欄位說明 |
| 9 | creditCardReceiptType | 信用卡簽單類型︰ 1=列印全部(商店存根&持卡人存根) 2=只印持卡人存根 | string | 當交易模式代號為1時必要,Lib 0.0.51 |
| 10 | onePassEcho | 一碼付echo | string | 一碼付App交易使用的echo,其內容值為的JSON Object { "storeUid": "...", "storeName": "...", "externalStoreUid": "...", "externalStoreName": "..." } |
| 11 | receiptType | 收據類型︰ 1=免用統一發票收據 2=農漁民收據 | string | Lib 0.2.3 |
| 12 | isPrintOrderDetailsReceipt | 是否列印交易明細 | boolean | |
| 13 | actualPayMode | 自行收款付款方式 | string | 非必要,請參考自行收款付款方式說明,當交易模式代號為37時,這裡帶入的值表示以此種方式自行收款,但在金流交易會有對應的紀錄 |
進行交易查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 |
進行退款
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | uid | appResponse回傳對應該訂單的uid | string | 必要 |
| 3 | key | appResponse回傳對應該訂單的key | string | 必要 |
| 4 | invoiceState | 若有開立電子發票,指定電子發票使用作廢或折讓︰ 4=作廢或作廢重開 6=折讓 | string | 必要,注意:跨發票月份無法作廢 |
| 5 | creditCardReceiptType | 信用卡簽單類型︰ 1=列印全部(商店存根&持卡人存根) 2=只印持卡人存根 | string | 非必要,當原始交易為信用卡交易時才有作用,Lib 0.0.51 |
| 6 | orderId | 欲退款該訂單的編號 | string | 必要 |
進行TAP初始化(只有MYPAY TAP APP支援)
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 |
進行TAP交易(只有MYPAY TAP APP支援)
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | currency | 交易幣別︰ TWD=新台幣 CNY=人民幣 | string | 必要 |
| 3 | sendReceiptInfo | 傳送電子簽單需要的資訊 | string | 非必要,目前支援手機號碼與Email |
| 4 | itemList | 商品列表 | list | 必要,請參考商品列表欄位說明 |
| 5 | invoice | 發票資料 | object | 非必要,請參考發票資料欄位說明 |
| 6 | isPrintOrderDetailsReceipt | 是否列印交易明細 | boolean |
進行TAP退款(只有MYPAY TAP APP支援)
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | storeUid | 特約商店商務代號 | string | 必要 |
| 2 | userId | 該消費者在特店中註冊帳號名稱。黑名單機制︰被列入黑名單,則無法進行交易。風險管理機制︰特店模式中,可設定該帳號的交易次數、單筆金額與交易上限;代收付模式,則無法自行設定。 | string | 必要 |
| 3 | uid | appResponse回傳對應該訂單的uid | string | 必要 |
| 4 | orderId | 欲退款該訂單的編號 | string | 必要 |
| 5 | amount | 欲退款該訂單的總金額 | string | 必要 |
進行一卡通詢卡
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | 其它動作Request的共同欄位 | 請參考其它動作Request共同欄位說明 | |
| 2 | type | 詢卡類型︰ 1=快速詢卡 2=離線詢卡 3=連線詢卡 | int | 詢卡類型為1時表示欲查詢該卡片是否為一卡通票卡,為2時表示欲查詢目前票卡的餘額,為3時表示欲查詢目前票卡的餘額與相關資料(通常在票卡查詢機使用) |
| 3 | orderId | 訂單編號 | string | 當詢卡類型為3時必要,最大長度為30 |
進行一卡通交易
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | 其它動作Request的共同欄位 | 請參考其它動作Request共同欄位說明 | |
| 2 | type | 交易類型︰ 1=扣值交易 2=取消扣值交易 3=現金加值交易 4=取消現金加值交易 5=退貨加值交易 | int | |
| 3 | amount | 訂單總金額(每項商品之總價加總) | string | 必要 |
| 4 | orderId | 訂單編號 | string | 當交易類型為1、3、5時必要,且交易類型為5時,傳入的值必須與對應的扣值交易之orderId相同,最大長度為30 |
| 5 | rrn | 交易Response回傳的uid | string | 當交易類型為2、4、5時必要 |
| 6 | itemList | 商品列表 | list | 當交易類型為1時才有作用,請參考商品列表欄位說明 |
| 7 | invoice | 發票資料 | object | 當交易類型為1時才有作用,請參考發票資料欄位說明 |
進行一卡通結班
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | 其它動作Request的共同欄位 | 請參考其它動作Request共同欄位說明 |
進行列印
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | titleType | 發票標題類型︰ 1=文字 2=圖片URL | string | |
| 3 | title | 發票標題資料 | string | 依發票標題類型決定資料的內容為標題文字或圖片網址 |
| 4 | year | 發票年 | string | |
| 5 | month | 發票月 | string | |
| 6 | dateTime | 發票時間 | string | |
| 7 | invoiceNo | 發票號碼 | string | |
| 8 | sellerId | 賣方統編 | string | |
| 9 | buyerId | 買方統編 | string | |
| 10 | randomCode | 隨機碼 | string | |
| 11 | middleBarcode | 發票中間barcode | string | |
| 12 | leftQrCode | 發票左邊Qr Code | string | |
| 13 | rightQrCode | 發票右邊Qr Code | string | |
| 14 | taxType | 發票稅率類型︰ 1=應稅 2=零稅率 3=免稅 | string | |
| 15 | invoiceType | 發票類型︰ 1=正式發票 2=補印發票 | string | |
| 16 | itemList | 商品列表 | list | 請參考商品列表欄位說明 |
| 17 | logo | 發票標題圖片的data | byte array | 發票標題類型為2才有作用 |
| 18 | logoBase64 | 發票標題圖片的data (Base64編碼) | string | 發票標題類型為2且logo為null時才有作用,Lib 0.0.45 |
| 19 | printMode | 列印模式︰ 1=發票加明細 2=發票 3=明細 4=重印簽單 | String | 4加入於Lib 0.0.50 |
| 20 | businessEntity | 公司名或商店名 | String | |
| 21 | businessDay | 營業日 | String | |
| 22 | phone | 電話 | String | |
| 23 | address | 地址 | String | |
| 24 | uid | appResponse回傳對應該訂單的uid | string | 當重印簽單時必要,Lib 0.0.50 |
| 25 | key | appResponse回傳對應該訂單的key | string | 當重印簽單時必要,Lib 0.0.50 |
| 26 | creditCardReceiptType | 信用卡簽單類型︰ 1=列印全部(商店存根&持卡人存根) 2=只印持卡人存根 | string | 當重印簽單時必要,Lib 0.0.51 |
進行掃碼回傳
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | 其它動作Request的共同欄位 | 請參考其它動作Request共同欄位說明 |
進行查詢合作夥伴折扣碼
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | 其它動作Request的共同欄位 | 請參考其它動作Request共同欄位說明 | |
| 2 | storeName | 交易特店名稱 | string | |
| 3 | partner | 合作夥伴資料 | object | 請參考合作夥伴欄位說明 |
進行取得特店支援之支付方式
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | 其它動作Request的共同欄位 | 請參考其它動作Request共同欄位說明 | |
| 2 | currency | 交易幣別 | string | 必要 |
進行取得自行收款設定
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | 其它動作Request的共同欄位 | 請參考其它動作Request共同欄位說明 |
進行後開立發票
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | 其它動作Request的共同欄位 | 請參考其它動作Request共同欄位說明 | |
| 2 | uid | appResponse回傳對應該訂單的uid | string | 必要 |
| 3 | key | appResponse回傳對應該訂單的key | string | 必要 |
| 4 | orderId | 串接方訂單編號 | string | 必要 |
| 5 | invoice | 發票資料 | object | 非必要,請參考發票資料欄位說明 |
| 6 | configWithUi | 是否使用發票開立設定頁面手動設定開立的參數 | boolean | 當設定為true時,將忽略invoice的值,改由頁面中的設定值為最後開立的參數 |
進入金流訂單列表頁
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | MYPAY頁面Request的共同欄位 | 請參考MYPAY頁面Request共同欄位說明 |
進入點餐單列表頁
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | MYPAY頁面Request的共同欄位 | 請參考MYPAY頁面Request共同欄位說明 |
進入發票管理頁
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | MYPAY頁面Request的共同欄位 | 請參考MYPAY頁面Request共同欄位說明 |
進入收據管理頁
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | MYPAY頁面Request的共同欄位 | 請參考MYPAY頁面Request共同欄位說明 |
進入印表機設定頁
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | MYPAY頁面Request的共同欄位 | 請參考MYPAY頁面Request共同欄位說明 |
進入交易回傳設定頁
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | MYPAY頁面Request的共同欄位 | 請參考MYPAY頁面Request共同欄位說明 |
進入結帳報表頁
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | MYPAY頁面Request的共同欄位 | 請參考MYPAY頁面Request共同欄位說明 |
進入金流訂單明細頁
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | MYPAY頁面Request的共同欄位 | 請參考MYPAY頁面Request共同欄位說明 | |
| 2 | uid | appResponse回傳對應該訂單的uid | string | 必要 |
| 3 | orderId | 欲查詢該訂單的編號 | string | 必要 |
| 4 | amount | 欲查詢該訂單的總金額 | string | 必要 |
進入裝置設定頁
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | MYPAY頁面Request的共同欄位 | 請參考MYPAY頁面Request共同欄位說明 |
進入會員API設定頁
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | MYPAY頁面Request的共同欄位 | 請參考MYPAY頁面Request共同欄位說明 |
進入會員累扣點頁
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | MYPAY頁面Request的共同欄位 | 請參考MYPAY頁面Request共同欄位說明 |
進入使用優惠券頁
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | MYPAY頁面Request的共同欄位 | 請參考MYPAY頁面Request共同欄位說明 |
進行39Buy登入
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 |
進行39Buy登出
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
進行39Buy驗證appToken
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
進行39Buy新增產品分類
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | level | 分類層級 | int | 必要,由1往上加,請勿跳段,以免造成錯誤 |
| 4 | zhTwName | 分類繁體名稱 | string | 必要 |
| 5 | status | 啟用狀態︰ 0=關閉 1=啟用 | int |
進行39Buy修改產品分類
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | uid | appResponse回傳對應該分類的uid | string | 必要 |
| 4 | level | 分類層級 | int | 必要,由1往上加,請勿跳段,以免造成錯誤 |
| 5 | zhTwName | 分類繁體名稱 | string | 必要 |
| 6 | status | 啟用狀態︰ 0=關閉 1=啟用 | int |
進行39Buy產品分類列表查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 查詢共同欄位 | 39Buy查詢Request的共同欄位 | 請參考39Buy查詢Request共同欄位說明 | |
| 4 | status | 啟用狀態︰ 0=關閉 1=啟用 | int |
進行39Buy產品分類明細查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | uid | appResponse回傳對應該分類的uid | string | 必要 |
進行39Buy產品分類關聯查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
進行39Buy產品分類關聯更新
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | relationalData | 關聯資料,範例如下所示,id為該分類的uid,data為該分類底下對應的分類層級資料,依此例子來說︰uid=14為最上層,它下層為uid=15與uid=16,而uid=15下層又有uid=17、uid=18跟uid=19,接著uid=16下層又有uid=17跟uid=18 | JSON Array string | 必要 |
[
{
"id":"14",
"data":[
{
"id":"15",
"data":[
{
"id":"17",
"data":[
]
},
{
"id":"18",
"data":[
]
},
{
"id":"19",
"data":[
]
}
]
},
{
"id":"16",
"data":[
{
"id":"17",
"data":[
]
},
{
"id":"18",
"data":[
]
}
]
}
]
}
]進行39Buy產品列表查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 查詢共同欄位 | 39Buy查詢Request的共同欄位 | 請參考39Buy查詢Request共同欄位說明 | |
| 4 | type | 產品類型 | int | 必要,請參考39Buy訂單產品類型說明 |
| 5 | productWitch | 產品是否開放︰ 0=否 1=是 2=不限制 | int | 預設2 |
進行39Buy產品明細查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | uid | 對應該產品的uid | string | 必要 |
進行39Buy訂單列表查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | page | 頁數 | int | 預設1 |
| 4 | record | 一頁多少筆資料 | int | 預設10 |
| 5 | type | 產品類型 | int | 預設0,請參考39Buy訂單產品類型說明 |
| 6 | retCode | 付款狀態 | string | 請參考39Buy付款狀態說明 |
| 7 | refundRetCode | 退款狀態 | string | 請參考39Buy退款狀態說明 |
| 8 | orderDateStart | 訂單日期-起,格式為yyyy-MM-dd HH:mm:ss | string | |
| 9 | orderDateEnd | 訂單日期-迄,格式為yyyy-MM-dd HH:mm:ss | string | |
| 10 | payMode | 付款方式 | string | 預設0,請參考付款方式說明 |
| 11 | searchType | 查詢類型︰ 1=訂購人姓名 2=訂單編號 3=發票號碼 | int | |
| 12 | searchKeyword | 依查詢類型的項目查找的關鍵字 | string |
進行39Buy訂單明細查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | uid | 對應該訂單的uid | string | 必要 |
進行39Buy新增一般產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 新增修改產品共同欄位 | 新增修改產品Request的共同欄位 | 請參考39Buy新增修改產品Request共同欄位說明 | |
| 4 | specData | 產品副檔資料 | list | 必要,請參考39Buy產品規格欄位說明 |
進行39Buy修改一般產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 新增修改產品共同欄位 | 新增修改產品Request的共同欄位 | 請參考39Buy新增修改產品Request共同欄位說明 | |
| 4 | 修改產品共同欄位 | 修改產品Request的共同欄位 | 請參考39Buy修改產品Request共同欄位說明 | |
| 5 | specData | 產品副檔資料 | list | 必要,請參考39Buy產品規格欄位說明 |
進行39Buy新增捐款產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 新增修改產品共同欄位 | 新增修改產品Request的共同欄位 | 請參考39Buy新增修改產品Request共同欄位說明 | |
| 4 | specData | 產品副檔資料 | list | 必要,請參考39Buy產品規格欄位說明 |
| 5 | unknown | 是否匿名捐款︰ 0=否 1=是 | int | 預設0 |
| 6 | donorInfoSwitch | 捐款人資訊開關︰ 0=否 1=開 | int | 預設0,非匿名捐款時,強制為1 |
進行39Buy修改捐款產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 新增修改產品共同欄位 | 新增修改產品Request的共同欄位 | 請參考39Buy新增修改產品Request共同欄位說明 | |
| 4 | 修改產品共同欄位 | 修改產品Request的共同欄位 | 請參考39Buy修改產品Request共同欄位說明 | |
| 5 | specData | 產品副檔資料 | list | 必要,請參考39Buy產品規格欄位說明 |
進行39Buy新增一碼付產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 新增修改產品共同欄位 | 新增修改產品Request的共同欄位 | 請參考39Buy新增修改產品Request共同欄位說明 | |
| 4 | specData | 產品副檔資料 | list | 必要,請參考39Buy產品規格欄位說明 |
進行39Buy修改一碼付產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 新增修改產品共同欄位 | 新增修改產品Request的共同欄位 | 請參考39Buy新增修改產品Request共同欄位說明 | |
| 4 | 修改產品共同欄位 | 修改產品Request的共同欄位 | 請參考39Buy修改產品Request共同欄位說明 | |
| 5 | specData | 產品副檔資料 | list | 必要,請參考39Buy產品規格欄位說明 |
進行39Buy新增點燈產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 新增修改產品共同欄位 | 新增修改產品Request的共同欄位 | 請參考39Buy新增修改產品Request共同欄位說明 | |
| 4 | specData | 產品副檔資料 | list | 必要,請參考39Buy產品規格欄位說明 |
進行39Buy修改點燈產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 新增修改產品共同欄位 | 新增修改產品Request的共同欄位 | 請參考39Buy新增修改產品Request共同欄位說明 | |
| 4 | 修改產品共同欄位 | 修改產品Request的共同欄位 | 請參考39Buy修改產品Request共同欄位說明 | |
| 5 | specData | 產品副檔資料 | list | 必要,請參考39Buy產品規格欄位說明 |
進行39Buy新增超渡產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 新增修改產品共同欄位 | 新增修改產品Request的共同欄位 | 請參考39Buy新增修改產品Request共同欄位說明 | |
| 4 | specData | 超渡產品副檔資料 | list | 必要,請參考39Buy超渡產品規格欄位說明 |
進行39Buy修改超渡產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 新增修改產品共同欄位 | 新增修改產品Request的共同欄位 | 請參考39Buy新增修改產品Request共同欄位說明 | |
| 4 | 修改產品共同欄位 | 修改產品Request的共同欄位 | 請參考39Buy修改產品Request共同欄位說明 | |
| 5 | specData | 超渡產品副檔資料 | list | 必要,請參考39Buy超渡產品規格欄位說明 |
進行39Buy一般交易
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 交易共同欄位 | 交易Request的共同欄位 | 請參考39Buy交易Request共同欄位說明 | |
| 4 | items | 購買的商品 | list | 必要,請參考39Buy交易產品欄位說明 |
進行39Buy捐款交易
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 交易共同欄位 | 交易Request的共同欄位 | 請參考39Buy交易Request共同欄位說明 | |
| 4 | items | 購買的商品 | object | 必要,請參考39Buy交易產品欄位說明 |
| 5 | donorAskReceipt | 捐款人索取收據︰ 0=不索取 1=索取 | int | 預設0 |
| 6 | donorAskMode | 捐款人索取方式︰ 0=無 1=單筆 2=年度 | int | 預設0 |
| 7 | donorIsNotificationTax | 捐款人上傳國稅局︰ 0=否 1=是 | int | 預設0 |
| 8 | donorType | 捐款人類型︰ 0=無 1=個人 2=法人 | int | 預設0 |
| 9 | donorId | 捐款人編號(身分證字號/公司編號) | string | |
| 10 | donorName | 捐款人名稱(捐款人/捐款公司)(加密) | string | |
| 11 | donorCountry | 捐款人的收據國別 | string | |
| 12 | donorCity | 捐款人的收據縣市 | string | |
| 13 | donorDistricts | 捐款人的收據鄉鎮區 | string | |
| 14 | donorAddress | 捐款人的收據地址 | string |
進行39Buy一碼付交易
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 交易共同欄位 | 交易Request的共同欄位 | 請參考39Buy交易Request共同欄位說明 | |
| 4 | items | 購買的商品 | list | 必要,請參考39Buy交易產品欄位說明 |
進行39Buy點燈交易
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 慈善交易共同欄位 | 慈善交易Request的共同欄位 | 請參考39Buy慈善交易Request共同欄位說明 | |
| 4 | donateList | 點燈名單列表 | list | 必要,請參考39Buy點燈名單欄位說明 |
進行39Buy超渡交易
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 共同欄位 | Request的共同欄位 | 請參考Request共同欄位說明 | |
| 2 | appToken | 當次登入取得的token | string | 必要 |
| 3 | 慈善交易共同欄位 | 慈善交易Request的共同欄位 | 請參考39Buy慈善交易Request共同欄位說明 | |
| 4 | ghostFestivalItem | 超渡項目 | string | 必要 |
| 5 | releaseUserName | 超渡對像名稱 | string | 必要 |
| 6 | releaseUserBirthdayType | 超渡對象生日類型︰ 1=國曆 2=農曆 | int | 預設1 |
| 7 | releaseUserBirthday | 超渡對象生日,格式為yyyy-MM-dd | string | 如果不知生日時間,請統一帶9999-99-99 |
| 8 | releaseUserBirthdayTime | 超渡對象生辰(00 ~ 23) | string | 如果不知生日期間,請統一帶99 |
| 9 | releaseUserBirthdayLeap | 超渡對象生日是否為閏月︰ 0=否 1=是 | int | 預設0 |
| 10 | releaseUserDieDayType | 超渡對象歿日類型1︰ 1=國曆 2=農曆 | int | 預設1 |
| 11 | releaseUserDieDay | 超渡對象歿日,格式為yyyy-MM-dd | string | 如果不知歿日時間,請統一帶9999-99-99 |
| 12 | releaseUserDieDayTime | 超渡對象歿日 | string | 如果不知歿日期間,請統一帶99 |
| 13 | releaseUserDieDayLeap | 超渡對象歿日是否為閏月︰ 0=否 1=是 | int | |
| 14 | releaseUserZipCode | 超渡對象郵遞區號 | string | 必要 |
| 15 | releaseUserCountry | 超渡對象牌(塔)國家 | string | 必要 |
| 16 | releaseUserCity | 超渡對象牌(塔)城市 | string | 必要 |
| 17 | releaseUserDistrict | 超渡對象牌(塔)區域 | string | 必要 |
| 18 | releaseUserAddress | 超渡對象牌(塔)地址 | string | 必要 |
ActionDetails做為AppResponse使用時
在串接方App的onActivityResult中,請使用自行定義的requestCode判斷為那一種AppRequest後再進行轉換,以避免非預期的錯誤。 必須將ActionDetails的data轉換成你的AppResponse。
進行交易
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼 | string | 請參考回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | uid | 對應該訂單的uid | string | |
| 4 | key | 對應該訂單的key | string | |
| 5 | finishTime | 交易時間 | string | |
| 6 | cardNo | 卡號 | string | |
| 7 | aCode | 授權碼 | string | 為信用卡交易時才會有值 |
| 8 | orderId | 串接方訂單編號 | string | |
| 9 | userId | 該消費者在特店中註冊帳號名稱 | string | |
| 10 | amount | 交易金額 | string | |
| 11 | actualAmount | 實際交易金額 | string | |
| 12 | currency | 交易幣別 | string | |
| 13 | actualCurrency | 實際交易幣別 | string | |
| 14 | pfn | 付款類型 | string | 請參考付款類型說明 |
| 15 | echo | echo資料 | object | 請參考echo欄位說明 |
| 16 | itemList | 訂單商品項目 | list | 請參考商品列表欄位說明 |
| 17 | invoice | 對應該訂單的發票資訊 | object | 請參考訂單發票欄位說明 |
| 18 | invoiceCount | 線上發票剩餘張數,指的是目前後台所剩下的發票張數,當值為-1時表示無法取得線上目前的剩餘張數,可與剩餘張數零張(值為0)作區分 | int | App 5.0.3 |
| 19 | deviceInvoiceCount | 設備發票剩餘張數,指的是目前設備上還有多少發票號碼可用 | int | App 5.0.3 |
進行交易查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼 | string | 請參考回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | orderList | 訂單列表 | list | 請參考訂單列表欄位說明 |
進行退款
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼 | string | 請參考回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | uid | 對應該訂單的uid | string | |
| 4 | key | 對應該訂單的key | string | |
| 5 | finishTime | 交易時間 | string | |
| 6 | cardNo | 卡號 | string | |
| 7 | aCode | 授權碼 | string | 為信用卡交易時才會有值 |
| 8 | orderId | 串接方訂單編號 | string | |
| 9 | userId | 該消費者在特店中註冊帳號名稱 | string | |
| 10 | amount | 交易金額 | string | |
| 11 | actualAmount | 實際交易金額 | string | |
| 12 | currency | 交易幣別 | string | |
| 13 | actualCurrency | 實際交易幣別 | string | |
| 14 | pfn | 付款類型 | string | 請參考付款類型說明 |
| 15 | echo | echo資料 | object | 請參考echo欄位說明 |
進行TAP初始化(只有MYPAY TAP APP支援)
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼 | string | 請參考回傳碼說明 |
| 2 | msg | 回傳訊息 | string |
進行TAP交易(只有MYPAY TAP APP支援)
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼 | string | 請參考回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | uid | 對應該訂單的uid | string | |
| 4 | key | 對應該訂單的key | string | |
| 5 | finishTime | 交易時間 | string | |
| 6 | cardNo | 卡號 | string | |
| 7 | aCode | 授權碼 | string | |
| 8 | authCode | 授權碼 | string | |
| 9 | orderId | 串接方訂單編號 | string | |
| 10 | userId | 該消費者在特店中註冊帳號名稱 | string | |
| 11 | amount | 交易金額 | string | |
| 12 | actualAmount | 實際交易金額 | string | |
| 13 | currency | 交易幣別 | string | |
| 14 | actualCurrency | 實際交易幣別 | string | |
| 15 | pfn | 付款類型 | string | 請參考付款類型說明 |
| 16 | transactionId | 用於查詢該交易的id | string | |
| 17 | itemList | 訂單商品項目 | list | 請參考商品列表欄位說明 |
| 18 | invoice | 對應該訂單的發票資訊 | object | 請參考訂單發票欄位說明 |
| 19 | invoiceCount | 線上發票剩餘張數,指的是目前後台所剩下的發票張數,當值為-1時表示無法取得線上目前的剩餘張數,可與剩餘張數零張(值為0)作區分 | int | App 5.0.3 |
| 20 | deviceInvoiceCount | 設備發票剩餘張數,指的是目前設備上還有多少發票號碼可用 | int | App 5.0.3 |
進行TAP退款(只有MYPAY TAP APP支援)
注意︰
- TAP交易的取消或退款動作只能在MYPAY TAP APP的訂單明細頁中或使用TAP退款的方式執行(SDK限制),無法透過直接交易的退款動作進行退款。
- 當使用PAGE_MYPAY_ORDER_DETAILS跳到指定的訂單明細頁時,若該交易為TAP交易,在頁面中點選交易取消或退款時,可以在取消或退款結束後,在串接方App接收到回傳的結果。
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼 | string | 請參考回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | uid | 對應該訂單的uid | string | |
| 4 | key | 對應該訂單的key | string | |
| 5 | finishTime | 交易時間 | string | |
| 6 | cardNo | 卡號 | string | |
| 7 | aCode | 授權碼 | string | |
| 8 | authCode | 授權碼 | string | |
| 9 | orderId | 串接方訂單編號 | string | |
| 10 | userId | 該消費者在特店中註冊帳號名稱 | string | |
| 11 | amount | 交易金額 | string | |
| 12 | actualAmount | 實際交易金額 | string | |
| 13 | currency | 交易幣別 | string | |
| 14 | actualCurrency | 實際交易幣別 | string | |
| 15 | pfn | 付款類型 | string | 請參考付款類型說明 |
| 16 | transactionId | 用於查詢該交易的id | string | |
| 17 | itemList | 訂單商品項目 | list | 請參考商品列表欄位說明 |
進行一卡通詢卡
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼 | string | 請參考回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | uid | 唯一交易序號 | string | 當詢卡類型為3時才存在 |
| 4 | finishTime | 交易時間 | string | 當詢卡類型為3時才存在 |
| 5 | cardNo | 卡號 | string | 當詢卡類型為3時才存在 |
| 6 | aCode | 交易授權碼 | string | 當詢卡類型為3時才存在 |
| 7 | orderId | 串接方訂單編號 | string | 當詢卡類型為3時才存在 |
| 8 | userId | 該消費者在特店中註冊帳號名稱 | string | 當詢卡類型為3時才存在 |
| 9 | amount | 交易金額 | string | 當詢卡類型為3時才存在 |
| 10 | currency | 交易幣別 | string | 當詢卡類型為3時才存在 |
| 11 | pfn | 付款類型 | string | 當詢卡類型為3時才存在,請參考付款類型說明 |
進行一卡通交易
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼 | string | 請參考回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | uid | 唯一交易序號 | string | |
| 4 | finishTime | 交易時間 | string | |
| 5 | cardNo | 卡號 | string | |
| 6 | aCode | 交易授權碼 | string | |
| 7 | orderId | 串接方訂單編號 | string | |
| 8 | userId | 該消費者在特店中註冊帳號名稱 | string | |
| 9 | amount | 交易金額 | string | |
| 10 | currency | 交易幣別 | string | |
| 11 | pfn | 付款類型 | string | 請參考付款類型說明 |
進行一卡通結班
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼 | string | 請參考回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | uid | 對應該訂單的uid | string | |
| 4 | batchNumber | 當次結班流水號 | string | |
| 5 | totalCounter | 總交易筆數 | string | |
| 6 | totalAmount | 總交易金額 | string | |
| 7 | queryCardCounter | 連線詢卡交易筆數 | string | |
| 8 | queryCardAmount | 連線詢卡交易金額加總 | string | |
| 9 | redeemCounter | 扣值交易筆數 | string | |
| 10 | redeemAmount | 扣值交易金額加總 | string | |
| 11 | cancelRedeemCounter | 取消扣值交易筆數 | string | |
| 12 | cancelRedeemAmount | 取消扣值交易金額加總 | string | |
| 13 | cancelReloadCounter | 取消現金加值交易筆數 | string | |
| 14 | cancelReloadAmount | 取消現金加值交易金額加總 | string | |
| 15 | autoReloadCounter | 前台自動加值交易筆數 | string | |
| 16 | autoReloadAmount | 前台自動加值交易金額加總 | string | |
| 17 | cashReloadCounter | 現金加值交易筆數 | string | |
| 18 | cashReloadAmount | 現金加值交易金額加總 | string | |
| 19 | refundCounter | 退貨加值交易筆數 | string | |
| 20 | refundAmount | 退貨加值交易金額加總 | string | |
| 21 | returnOverReloadCounter | 溢扣反還加值交易筆數 | string | |
| 22 | returnOverReloadAmount | 溢扣反還加值交易金額加總 | string | |
| 23 | balanceRecoveryCounter | 票值回覆交易筆數 | string | |
| 24 | balanceRecoveryAmount | 票值回覆交易金額加總 | string | |
| 25 | autoReloadOffCounter | 關閉自動加值交易筆數 | string | |
| 26 | autoReloadOffAmount | 關閉自動加值交易金額加總 | string | |
| 27 | autoReloadOnCounter | 開啟自動加值交易筆數 | string | |
| 28 | autoReloadOnAmount | 開啟自動加值交易金額加總 | string | |
| 29 | lockCardCounter | 鎖卡交易筆數 | string | |
| 30 | lockCardAmount | 鎖卡交易金額加總 | string | |
| 31 | changeCardCounter | 改卡交易筆數 | string | |
| 32 | changeCardAmount | 改卡交易金額加總 | string | |
| 33 | autoReloadBackendCounter | 後台自動加值交易筆數 | string | |
| 34 | autoReloadBackendAmount | 後台自動加值交易金額加總 | string | |
| 35 | nextBatchNumber | 次筆結班流水號 | string | |
| 36 | nextTotalCounter | 次筆結班總交易筆數 | string | |
| 37 | nextTotalAmount | 次筆結班總交易金額 | string | |
| 38 | nextQueryCardCounter | 次筆結班連線詢卡交易筆數 | string | |
| 39 | nextQueryCardAmount | 次筆結班連線詢卡交易金額加總 | string | |
| 40 | nextRedeemCounter | 次筆結班扣值交易筆數 | string | |
| 41 | nextRedeemAmount | 次筆結班扣值交易金額加總 | string | |
| 42 | nextCancelRedeemCounter | 次筆結班取消扣值交易筆數 | string | |
| 43 | nextCancelRedeemAmount | 次筆結班取消扣值交易金額加總 | string | |
| 44 | nextCancelReloadCounter | 次筆結班取消現金加值交易筆數 | string | |
| 45 | nextCancelReloadAmount | 次筆結班取消現金加值交易金額加總 | string | |
| 46 | nextAutoReloadCounter | 次筆結班前台自動加值交易筆數 | string | |
| 47 | nextAutoReloadAmount | 次筆結班前台自動加值交易金額加總 | string | |
| 48 | nextCashReloadCounter | 次筆結班現金加值交易筆數 | string | |
| 49 | nextCashReloadAmount | 次筆結班現金加值交易金額加總 | string | |
| 50 | nextRefundCounter | 次筆結班退貨加值交易筆數 | string | |
| 51 | nextRefundAmount | 次筆結班退貨加值交易金額加總 | string | |
| 52 | nextReturnOverReloadCounter | 次筆結班溢扣反還加值交易筆數 | string | |
| 53 | nextReturnOverReloadAmount | 次筆結班溢扣反還加值交易金額加總 | string | |
| 54 | nextBalanceRecoveryCounter | 次筆結班票值回覆交易筆數 | string | |
| 55 | nextBalanceRecoveryAmount | 次筆結班票值回覆交易金額加總 | string | |
| 56 | nextAutoReloadOffCounter | 次筆結班關閉自動加值交易筆數 | string | |
| 57 | nextAutoReloadOffAmount | 次筆結班關閉自動加值交易金額加總 | string | |
| 58 | nextAutoReloadOnCounter | 次筆結班開啟自動加值交易筆數 | string | |
| 59 | nextAutoReloadOnAmount | 次筆結班開啟自動加值交易金額加總 | string | |
| 60 | nextLockCardCounter | 次筆結班鎖卡交易筆數 | string | |
| 61 | nextLockCardAmount | 次筆結班鎖卡交易金額加總 | string | |
| 62 | nextChangeCardCounter | 次筆結班改卡交易筆數 | string | |
| 63 | nextChangeCardAmount | 次筆結班改卡交易金額加總 | string | |
| 64 | nextAutoReloadBackendCounter | 次筆結班後台自動加值交易筆數 | string | |
| 65 | nextAutoReloadBackendAmount | 次筆結班後台自動加值交易金額加總 | string |
進行列印
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼 | string | 請參考回傳碼說明 |
| 2 | msg | 回傳訊息 | string |
進行掃碼回傳
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼 | string | 請參考回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | result | 掃碼的結果 | string |
進行查詢合作夥伴折扣碼
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼 | string | 請參考回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | result | 查詢折扣碼的結果 | string |
進行取得特店支援之支付方式
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼 | string | 請參考回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | payModeIdList | 特店支援之支付方式列表 | string list | 請參考付款方式說明(對應付款類型),若值為-1,請直接忽略。請忽略此列表中包含的一卡通支付方式,而直接判斷設備支援之支付方式列表是否有包含一卡通 |
| 4 | devicePayModeIdList | 設備支援之支付方式列表 | string list | 請參考付款方式說明(對應付款類型),若值為-1,請直接忽略。若欲判斷是否支援一卡通,請判斷此列表是否包含一卡通的支付方式,有則表示有支援,反之則沒有支援 |
進行後開立發票
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼 | string | 請參考回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | invoice | 對應該訂單的發票資訊 | object | 請參考訂單發票欄位說明 |
進行39Buy交易登入
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 39Buy回傳碼 | string | 請參考39Buy回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | storeUid | 大特店或特約商店uid | string | |
| 4 | userName | 登入者名稱 | string | |
| 5 | userLoginId | 登入者ID | string | |
| 6 | companyName | 公司名稱 | string | |
| 7 | companyNickName | 公司簡稱 | string | |
| 8 | appToken | 當次登入取得的token | string | |
| 9 | permissionList | 功能權限列表 | string array | |
| 10 | deviceId | 設備ID | string |
進行39Buy登出
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 39Buy回傳碼 | string | 請參考39Buy回傳碼說明 |
| 2 | msg | 回傳訊息 | string |
進行39Buy驗證appToken
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 39Buy回傳碼 | string | 請參考39Buy回傳碼說明 |
| 2 | msg | 回傳訊息 | string |
進行39Buy新增產品分類
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼︰ A0000=新增成功 A0001=資料已存在 A9999=新增異常 | string | |
| 2 | msg | 回傳訊息 | string |
進行39Buy修改產品分類
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼︰ E0000=修改成功 E0001=資料已存在 E9999=修改異常 | string | |
| 2 | msg | 回傳訊息 | string |
進行39Buy產品分類列表查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 39Buy回傳碼 | string | 請參考39Buy回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | count | 資料筆數 | int | |
| 4 | data | 產品分類列表 | list | 請參考39Buy產品分類列表欄位說明 |
進行39Buy產品分類明細查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 39Buy回傳碼 | string | 請參考39Buy回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | uid | 分類uid | string | |
| 4 | zhTwName | 分類繁中名稱 | string | |
| 5 | level | 層級 | int | |
| 6 | status | 是否啟用︰ 0=否 1=是 | int |
進行39Buy產品分類關聯查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 39Buy回傳碼 | string | 請參考39Buy回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | data | 產品分類關聯列表 | list | 請參考39Buy產品分類關聯欄位說明 |
進行39Buy產品分類關聯更新
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 回傳碼︰ A0000=新增成功 A9999=新增異常 | string | |
| 2 | msg | 回傳訊息 | string |
進行39Buy產品列表查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 39Buy回傳碼 | string | 請參考39Buy回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | totalPage | 總頁數 | int | |
| 4 | nowPage | 目前頁數 | int | |
| 5 | data | 產品列表 | list | 請參考39Buy產品欄位說明 |
進行39Buy產品明細查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 39Buy回傳碼 | string | 請參考39Buy回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | uid | 產品uid | string | |
| 4 | storeUid | 特店代號 | string | |
| 5 | productNo | 產品編號 | string | |
| 6 | productType | 產品規格︰ 1=單規格 2=雙規格 3=三規格 99=無規格 | int | |
| 7 | type | 產品類型 | int | 請參考39Buy訂單產品類型說明 |
| 8 | productClass | 所屬上層分類的uid | string array | |
| 9 | zhTwName | 產品名稱(繁中) | string | |
| 10 | enUsName | 產品名稱(英文) | string | |
| 11 | zhCnName | 產品名稱(簡中) | string | |
| 12 | jaName | 產品名稱(日文) | string | |
| 13 | productSwitch | 產品狀態︰ 0=未開放購買 1=開放購買 2=草稿 3=結案 | int | |
| 14 | startOpenDate | 開放產品可購買開始時間 | string | |
| 15 | endOpenDate | 開放產品可購買結束時間 | string | |
| 16 | payMode | 付款方式 | string | 請參考付款方式說明 |
| 17 | textPeriod | 定期定額周期選項 | string | |
| 18 | regularTotal | 定期定額指定期數 | string | |
| 19 | zhTwProductDesc | 產品簡短說明(繁中) | string | |
| 20 | enUsProductDesc | 產品簡短說明(英文) | string | |
| 21 | zhCnProductDesc | 產品簡短說明(簡中) | string | |
| 22 | zhTwPageDesc | 頁面說明(繁中) | string | |
| 23 | enUsPageDesc | 頁面說明(英文) | string | |
| 24 | zhCnPageDesc | 頁面說明(簡中) | string | |
| 25 | shippingFeeTaiwan | 台灣地區的運費 | string | |
| 26 | freeShippingTaiwan | 台灣地區免費運金額門檻 | string | |
| 27 | shippingFeeIsland | 離島地區的運費 | string | |
| 28 | freeShippingIsland | 離島地區免費運金額門檻 | string | |
| 29 | shippingFeeChina | 大陸地區的運費 | string | |
| 30 | freeShippingChina | 大陸地區免費運金額門檻 | string | |
| 31 | shippingFeeOversea | 海外地區的運費 | string | |
| 32 | freeShippingOversea | 海外地區免費運金額門檻 | string | |
| 33 | buyerInfo | 購買該產品時買家的必要欄位︰ name=姓名 phone=電話 address=地址 mail=e-mail query_code=查詢碼 single_number=自取碼 memo=備註 payer_id=身份證字號 | string | |
| 34 | pickupType | 取貨方式︰ 0=無須取貨 1=線上下單宅配送貨 2=線上下單自取 3=門市下單宅配 4=門市下單自取 | string | |
| 35 | price | 定價 | string | |
| 36 | specialPrice | 售價 | string | |
| 37 | isReciprocal | 是否開放倒數計數︰ 0=否 1=是 | int | |
| 38 | quickPaySystem | 一碼付系統預設︰ 0=否 1=是 | int | |
| 39 | donorInfoSwitch | 捐款人資訊開關︰ 0=否 1=開 | int | |
| 40 | templateUid | 對應感謝狀樣板編號 | int | |
| 41 | shortUrl | 短網址 | string | |
| 42 | creator | 建立者uid | string | |
| 43 | updater | 修改者uid | string | |
| 44 | createdAt | 產品建立時間,格式為yyyy-MM-dd HH:mm:ss | string | |
| 45 | updatedAt | 產品修改時間,格式為yyyy-MM-dd HH:mm:ss | string | |
| 46 | specData | 產品明細規格 | list | 請參考39Buy產品明細規格欄位說明 |
| 47 | imgData | 產品圖片 | list | 請參考39Buy產品明細圖片欄位說明 |
進行39Buy訂單列表查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 39Buy回傳碼 | string | 請參考39Buy回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | total | 總金額 | string | |
| 4 | totalPage | 總頁數 | int | |
| 5 | nowPage | 目前頁數 | int | |
| 6 | data | 訂單列表 | list | 請參考39Buy訂單欄位說明 |
進行39Buy訂單明細查詢
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 39Buy回傳碼 | string | 請參考39Buy回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | uid | 訂單uid | string | |
| 4 | companyUid | 大特店代碼 | string | |
| 5 | launchUid | 發動方商務代號 | string | |
| 6 | launchLayer | 發動方層級︰ 1=agent 3=store | int | |
| 7 | storeUid | 訂單所屬特約商 | string | |
| 8 | storeOrderId | 廠商自訂訂單編號 | string | |
| 9 | orderDate | 訂單日期 | string | |
| 10 | shippingFee | 運費 | string | |
| 11 | orderTypeUid | 訂單產品類型 | int | 請參考39Buy訂單產品類型說明 |
| 12 | payModeUid | 付款方式 | int | |
| 13 | payerRealName | 付款人真實姓名(加密) | string | |
| 14 | payerIdType | 身分證類型︰ 1=身分證 2=統一證號 3=護照號碼 | int | 付款人為本國人為1,外國人為2或3 |
| 15 | payerId | 付款人身分證/統一證號/護照號碼 | string | |
| 16 | payerBirthday | 付款人生日,格式為yyyy-MM-dd | string | |
| 17 | payerPhoneCode | 付款人手機國碼 | string | |
| 18 | payerPhone | 付款人手機 | string | |
| 19 | payerMail | 付款人信箱 | string | |
| 20 | payerZipcode | 付款人郵遞區號 | string | |
| 21 | payerCountry | 付款人國籍 | string | |
| 22 | payerCity | 付款人居住城市 | string | |
| 23 | payerDistrict | 付款人居住區域 | string | |
| 24 | payerAddress | 付款人居住地址 | string | |
| 25 | consigneeRealName | 收件人真實姓名 | string | |
| 26 | consigneeBirthday | 收件人生日,格式為yyyy-MM-dd | string | |
| 27 | consigneePhoneCode | 收件人手機國碼 | string | |
| 28 | consigneePhone | 收件人手機 | string | |
| 29 | consigneeMail | 收件人信箱 | string | |
| 30 | consigneeZipcode | 收件人郵遞區號 | string | |
| 31 | consigneeCountry | 收件人國籍 | string | |
| 32 | consigneeCity | 收件人居住城市 | string | |
| 33 | consigneeDistrict | 收件人居住區域 | string | |
| 34 | consigneeAddress | 收件人居住地址 | string | |
| 35 | letterOfThanksMail | 感謝信收件人mail | string | |
| 36 | letterOfThanksName | 感謝信收件人姓名 | string | |
| 37 | payPrice | 消費金額 | string | |
| 38 | refundPayPrice | 退款金額 | string | |
| 39 | currencyCls | 幣別記錄 | string | |
| 40 | couponUid | 折扣卷對應uid | string | |
| 41 | cardNo | 遮碼卡號 | string | |
| 42 | aCode | 授權碼 | string | |
| 43 | transactionMode | 交易服務類型︰ 0=尚未進行閘道交易 1=代收代付 2=特店模式 | string | |
| 44 | supplierName | 交易之金融服務商 | string | |
| 45 | supplierCode | 交易之金融服務商代碼 | string | |
| 46 | discount | 折扣金額 | string | |
| 47 | redeem | 紅利兌換比例 | string | |
| 48 | retCode | 付款狀態 | string | 請參考39Buy付款狀態說明 |
| 49 | refundRetCode | 退款狀態 | string | 請參考39Buy退款狀態說明 |
| 50 | loanData | 貸款資料 | string | |
| 51 | pickupType | 取貨方式︰ 0=無須取貨 1=線上下單宅配送貨 2=線上下單自取 3=門市下單宅配 4=門市下單自取 | int | |
| 52 | pickupAvailable | 貨物狀態︰ 0=狀態 1=已出貨(ALL) 2=可取貨(店自取) 3=已取貨(店自取) 4=已送達(送貨) | int | |
| 53 | singleNumber | 貨運單號或取貨代碼 | string | |
| 54 | memo | 買家留言 | string | |
| 55 | treatmentMemo | 訂單處理註記 | string | |
| 56 | extraEcho | 使用api送來echo值的記錄區 | string | |
| 57 | sysEcho | 內部系統紀錄echo | string | |
| 58-62 | echo0 ~ ech4 | 自訂紀錄 | string | |
| 63 | queryCode | 訂單查詢碼 | string | |
| 64 | taxiCarNumber | 計程車車輛編號 | string | |
| 65 | taxiLicensePlateNumber | 計程車車牌號碼 | string | |
| 66 | feeType | 手續費類型︰ 1=單筆金額 2=單筆比例 3=比例+金額 4=比例+上限 | int | |
| 67 | feePrice | 手續費金額記錄所在 | string | |
| 68 | refundFeePrice | 退貨手續費金額紀錄 | string | |
| 69 | regular | 定期定額付費期數單位: W=每週扣款一次 F=雙週扣款一次 M=每月扣款一次 S=每季扣款一次 H=每半年扣款一次 A=每年扣款一次 | string | |
| 70 | regularTotal | 定期定額或分期付款、無卡分期總期數 | int | |
| 71 | regularFirstChargeDate | 定期定額或分期付款開始扣款日,格式為yyyy-MM-dd | string | |
| 72 | importOrderType | 匯入訂單的種類︰ 1=39buy系統自建的訂單 2=從他處匯入的捐款訂單 | int | |
| 73 | noneAdvanceCode | 無商品模式代碼 | string | |
| 74 | saleId | 歸屬於業務訂單 對應users->uid | string | |
| 75 | invoice | 發票回應資料 | int, string | 請參考39Buy發票回應資料欄位說明 |
| 76 | notificationType | 透過內部websocket (外部廠商使用此欄位為無效),僅限裝置交易通知,需搭配設備代號︰ 0=不通知 1=只通知交易 2=只通知發票 3=都通知 | int | |
| 77 | deviceNo | 設備代號 | string | |
| 78 | deviceName | 設備名稱 | string | |
| 79 | storeAddress | 發票明細地址 | string | |
| 80 | storeName | 發票明細名稱 | string | |
| 81 | storePhone | 發票明細服務電話 | string | |
| 82 | confirmShow | 卡機是否顯示訂單明細,給卡機操作者確認資料︰ 0=不顯示 1=顯示 | int | |
| 83 | confirmMessage | 卡機上顯示的文字 | string | |
| 84 | posConfirmStatus | 0=未回應 1=已同意 2=不同意 | int | |
| 85 | posConfirmDate | POS操作端回應時間 | string | |
| 86 | foodPaperTitle | 點餐單標題 | string | |
| 87 | fontSize | 點餐系統用-字型大小︰ 0=無設定 1=26 2=28 3=30 | int | |
| 88 | showTitleItem | 要顯示的項目︰ 1=桌號 2=人數 3=日期 4=時間 | string | |
| 89 | showMenuTitle | 要顯示的餐點標題︰ 1=菜名 2=量 3=口味 4=價錢 | string | |
| 90 | tableNumber | 點餐系統用-桌號 | string | |
| 91 | people | 點餐系統用-人數 | string | |
| 92 | distribute | 一筆訂單,多項商品,多項收件人紀錄,適用商品類型:17 | string | |
| 93 | appropriationDate | 代收付撥款日期 | string | |
| 94 | createdAt | 建立時間 | string | |
| 95 | updatedAt | 修改時間 | string | |
| 96 | details | 訂單產品細項列表 | list | 請參考39Buy訂單產品細項欄位說明 |
| 97 | records | 訂單付款資料列表 | list | 請參考39Buy訂單付款資料欄位說明 |
進行39Buy新增一般產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 新增產品回傳碼 | string | 請參考39Buy新增產品回傳碼說明 |
| 2 | msg | 回傳訊息 | string |
進行39Buy修改一般產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 修改產品回傳碼 | string | 請參考39Buy修改產品回傳碼說明 |
| 2 | msg | 回傳訊息 | string |
進行39Buy新增捐款產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 新增產品回傳碼 | string | 請參考39Buy新增產品回傳碼說明 |
| 2 | msg | 回傳訊息 | string |
進行39Buy修改捐款產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 修改產品回傳碼 | string | 請參考39Buy修改產品回傳碼說明 |
| 2 | msg | 回傳訊息 | string |
進行39Buy新增一碼付產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 新增產品回傳碼 | string | 請參考39Buy新增產品回傳碼說明 |
| 2 | msg | 回傳訊息 | string |
進行39Buy修改一碼付產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 修改產品回傳碼 | string | 請參考39Buy修改產品回傳碼說明 |
| 2 | msg | 回傳訊息 | string |
進行39Buy新增點燈產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 新增產品回傳碼 | string | 請參考39Buy新增產品回傳碼說明 |
| 2 | msg | 回傳訊息 | string |
進行39Buy修改點燈產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 修改產品回傳碼 | string | 請參考39Buy修改產品回傳碼說明 |
| 2 | msg | 回傳訊息 | string |
進行39Buy新增超渡產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 新增產品回傳碼 | string | 請參考39Buy新增產品回傳碼說明 |
| 2 | msg | 回傳訊息 | string |
進行39Buy修改超渡產品
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 修改產品回傳碼 | string | 請參考39Buy修改產品回傳碼說明 |
| 2 | msg | 回傳訊息 | string |
進行39Buy一般交易
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 交易回傳碼 | string | 請參考39Buy交易回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | feeMoney | 運費 | string | |
| 4 | errMsg | 參數異常訊息 | string list | |
| 5 | productError | 產品資料異常訊息 | list | 請參考39Buy產品資料異常訊息欄位說明 |
| 6 | orderResult | 訂單資料 | object | 請參考39Buy訂單資料欄位說明 |
進行39Buy捐款交易
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 交易回傳碼 | string | 請參考39Buy交易回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | feeMoney | 運費 | string | |
| 4 | errMsg | 參數異常訊息 | string list | |
| 5 | productError | 產品資料異常訊息 | list | 請參考39Buy產品資料異常訊息欄位說明 |
| 6 | orderResult | 訂單資料 | object | 請參考39Buy訂單資料欄位說明 |
進行39Buy一碼付交易
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 交易回傳碼 | string | 請參考39Buy交易回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | feeMoney | 運費 | string | |
| 4 | errMsg | 參數異常訊息 | string list | |
| 5 | productError | 產品資料異常訊息 | list | 請參考39Buy產品資料異常訊息欄位說明 |
| 6 | orderResult | 訂單資料 | object | 請參考39Buy訂單資料欄位說明 |
進行39Buy點燈交易
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 交易回傳碼 | string | 請參考39Buy交易回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | feeMoney | 運費 | string | |
| 4 | errMsg | 參數異常訊息 | string list | |
| 5 | productError | 產品資料異常訊息 | list | 請參考39Buy產品資料異常訊息欄位說明 |
| 6 | orderResult | 訂單資料 | object | 請參考39Buy訂單資料欄位說明 |
進行39Buy超渡交易
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | code | 交易回傳碼 | string | 請參考39Buy交易回傳碼說明 |
| 2 | msg | 回傳訊息 | string | |
| 3 | feeMoney | 運費 | string | |
| 4 | errMsg | 參數異常訊息 | string list | |
| 5 | productError | 產品資料異常訊息 | list | 請參考39Buy產品資料異常訊息欄位說明 |
| 6 | orderResult | 訂單資料 | object | 請參考39Buy訂單資料欄位說明 |
資料欄位說明
Request共同欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | storeUid | 特約商店商務代號 | string | 必要 |
| 2 | orderId | 訂單編號 | string | 交易必要,最大長度為30,且串接方必須自行確認每次發動交易請求時,orderId的值不會重複,否則將可能會造成重複交易的問題,導致顧客同一筆交易被扣款多次 |
| 3 | amount | 訂單總金額 | string | 交易必要,此金額必須和商品列表中所有的商品總價的加總金額相同(包括折扣項目),依使用之交易幣別決定支援的小數位數︰ TWD=新台幣(不支援小數) CNY=人民幣(小數2位) |
| 4 | userId | 該消費者在特店中註冊帳號名稱。黑名單機制︰被列入黑名單,則無法進行交易。風險管理機制︰特店模式中,可設定該帳號的交易次數、單筆金額與交易上限;代收付模式,則無法自行設定。 | string | 必要 |
| 5 | deviceName | 設備名稱 | string | 目前未使用,可為null |
| 6 | mode | 呼叫MYPAY APP的模式︰ 1=Cross App模式 2=API模式 | string | 預設為1,請勿修改此設定,否則將造成非預期的行為 |
| 7 | agentUid | 經銷商代號 | string | 使用經銷商模式時必要 |
其它動作Request共同欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | storeUid | 特約商店商務代號 | string | 必要 |
| 2 | userId | 該消費者在特店中註冊帳號名稱。黑名單機制︰被列入黑名單,則無法進行交易。風險管理機制︰特店模式中,可設定該帳號的交易次數、單筆金額與交易上限;代收付模式,則無法自行設定。 | string | 必要 |
MYPAY頁面Request共同欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | storeUid | 特約商店商務代號 | string | 必要 |
| 2 | userId | 該消費者在特店中註冊帳號名稱。黑名單機制︰被列入黑名單,則無法進行交易。風險管理機制︰特店模式中,可設定該帳號的交易次數、單筆金額與交易上限;代收付模式,則無法自行設定。 | string | 必要 |
商品列表欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | id | 商品編號 | string | 不能為空值(null或"") |
| 2 | name | 商品名稱 | string | 不能為空值(null或""),且名稱中不能包含冒號(:) |
| 3 | price | 商品單價 | string | 不能為空值(null或""),且若為折扣項目須為負值 |
| 4 | quantity | 商品數量 | string | 不能為空值(null或""),且必須大於0 |
| 5 | total | 商品總價(總價 = 單價 x 數量) | string | 不能為空值(null或""),且若為折扣項目須為負值 |
| 6 | isPrintOut | 是否可以在明細上印出 | boolean | Lib 0.0.34 |
消費者資料欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | name | 姓名 | string | |
| 2 | realName | 真實姓名 | string | |
| 3 | address | 地址 | string | |
| 4 | snType | 身分類型︰ 1=身分證 2=統一證號 3=護照號碼 | string | 消費者為本國人為1,外國人為2或3 |
| 5 | sn | 身分證/統一證號/護照號碼 | string | |
| 6 | phone | 家用電話 | string | |
| 7 | callingCode | 行動電話國碼 | string | 預設為886 |
| 8 | mobile | 行動電話 | string | |
| 9 | string | |||
| 10 | birthday | 生日 | string | |
| 11 | zipCode | 郵遞區號 | string | |
| 12 | country | 國籍 | string | |
| 13 | city | 居住城市 | string | |
| 14 | district | 居住區域 | string |
發票資料欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | rateType | 稅率類型︰ 1=應稅 2=零稅率 3=免稅 | int | |
| 2 | inputType | 類型︰ 1=雲端發票 2=發票捐贈 3=實體發票 4=外部發票 5=免用統一發票收據 6=農漁民收據 | string | 類型4、5、6只有39Buy支援 |
| 3 | cloudType | 雲端發票類型︰ 2=手機條碼 3=自然人憑證條碼 4=以E-Mail寄送 | string | 類型為1才有作用 |
| 4 | mobileCode | 手機條碼 | string | 雲端發票類型為2才有作用 |
| 5 | taxId | 統一編號 | string | 雲端發票類型為2才有作用 |
| 6 | naturalPerson | 自然人憑證條碼(格式請自行驗證) | string | 雲端發票類型為3才有作用 |
| 7 | mPostZone | E-Mail紙本寄送郵遞區號 | string | 雲端發票類型為4才有作用 |
| 8 | mAddress | E-Mail紙本寄送住址 | string | 雲端發票類型為4才有作用 |
| 9 | loveCode | 愛心碼(格式請自行驗證) | string | 類型為2才有作用 |
| 10 | b2bTitle | 發票抬頭 | string | 類型為3才有作用 |
| 11 | b2bId | 統一編號(格式請自行驗證) | string | 類型為3才有作用 |
| 12 | b2bPostZone | 郵遞區號 | string | 類型為3才有作用 |
| 13 | b2bAddress | 地址 | string | 類型為3才有作用 |
| 14 | issuerState | 發票是否開立狀態︰ 0=不開立電子發票 1=開立電子發票 2=依系統設定 | int | 預設2 |
| 15 | printMode | 列印類型模式︰ 0=不列印 2=發票 | string | 預設0 |
echo欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | value0 | 資料0 | string | |
| 2 | value1 | 資料1 | string | |
| 3 | value2 | 資料2 | string | |
| 4 | value3 | 資料3 | string | |
| 5 | value4 | 資料4 | string |
訂單列表欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | id | 訂單編號 | string | |
| 2 | uid | 對應該訂單的uid | string | |
| 3 | finishTime | 交易時間 | string | |
| 4 | pfn | 付款類型 | string | 請參考付款類型說明 |
| 5 | amount | 交易金額 | string | |
| 6 | actualAmount | 實際交易金額 | string | |
| 7 | currency | 交易幣別 | string | |
| 8 | actualCurrency | 實際交易幣別 | string | |
| 9 | string | 棄用 | ||
| 10 | key | 對應該訂單的key | string | |
| 11 | cardNo | 卡號 | string | |
| 12 | refundUidList | 對應該訂單的所有退款uid | string list | |
| 13 | status | 對應該訂單的交易狀態 | string | 請參考回傳碼說明 |
| 14 | statusMsg | 對應該訂單的交易狀態訊息 | string | |
| 15 | itemList | 訂單商品項目 | list | 請參考商品列表欄位說明 |
| 16 | invoice | 對應該訂單的發票資訊 | object | 請參考訂單發票欄位說明 |
訂單發票欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | state | 發票開立狀態︰ 0=不處理或已無效 1=等候處理中 2=發票開立成功 3=發票開立失敗(系統或特約商店發票相關設定不正確) 4=作癈 5=發票開立失敗(系統發生錯誤) 6=折讓 | int | |
| 2 | titleType | 發票標題類型︰ 1=文字 2=圖片URL | int | |
| 3 | rateType | 稅率類型︰ 1=應稅 2=零稅率 3=免稅 | int | |
| 4 | inputType | 類型︰ 0=未使用電子發票開立 1=雲端發票 2=發票捐贈 3=實體發票 | int | |
| 5 | cloudType | 雲端發票類型︰ 0=未使用 2=手機條碼 3=自然人憑證條碼 4=以E-Mail寄送 | int | |
| 6 | date | 發票開立日期 | string | |
| 7 | wordTrack | 發票字軌 | string | |
| 8 | number | 發票號碼 | string | |
| 9 | randomCode | 隨機碼 | string | |
| 10 | sellerId | 賣方統編 | string | |
| 11 | buyerId | 買方統編 | string | |
| 12 | leftQrCode | 發票左邊Qr Code | string | |
| 13 | middleBarcode | 發票中間barcode | string | |
| 14 | rightQrCode | 發票右邊Qr Code | string | |
| 15 | title | 發票標題資料 | string | 依發票標題類型決定資料的內容為標題文字或圖片 |
| 16 | amount | 電子發票銷售總額 | string | |
| 17 | salesAmount | 電子發票銷售額 | string | |
| 18 | taxAmount | 電子發票稅額 | string | |
| 19 | orderDetail | 電子發票全部產品明細 | string | JSON格式 |
| 20 | mobileCode | 手機條碼 | string | |
| 21 | taxId | 統一編號 | string | |
| 22 | naturalPerson | 自然人憑證條碼 | string | |
| 23 | mPostZone | E-Mail紙本寄送郵遞區號 | string | |
| 24 | mAddress | E-Mail紙本寄送住址 | string | |
| 25 | loveCode | 愛心碼 | string | |
| 26 | b2bTitle | 發票抬頭 | string | |
| 27 | b2bId | 統一編號 | string | |
| 28 | b2bPostZone | 郵遞區號 | string | |
| 29 | b2bAddress | 地址 | string |
合作夥伴欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | couponCode | 折扣碼 | string |
回傳碼說明
| 回傳碼 | 說明 | 備註 |
|---|---|---|
| 金流回傳碼 | 金流交易的回傳碼 | 請參考金流回傳碼說明 |
| App回傳碼 | MYPAY APP處理錯誤的回傳碼 | 請參考App回傳碼說明 |
| 一卡通回傳碼 | 一卡通交易的回傳碼 | 請參考一卡通回傳碼說明 |
金流回傳碼說明
| 回傳碼 | 說明 | 備註 |
|---|---|---|
| 100 | 資料錯誤,API收到資料,但是格式或資料錯誤 | |
| 200 | 資料正確,API收到正確資料,會接續下一步交易 | |
| 220 | 取消成功,API申請取消,取消訂單狀態為取消成功 | |
| 230 | 退款成功,API申請退款,申請退款成功時狀態 | |
| 250 | 付款成功,此次API交易,消費者付款成功 | |
| 260 | 交易成功 - 尚未付款完成,超商代碼繳費-請等候消費者繳費入帳完成付款或消費者放棄交易,API會再傳送一次結果: 250:代表消費者付款成功,此為最終結果 380:代表消費者沒有在時限內去繳費,逾期未去繳費,視同交易失敗,此為最終結果 | |
| 265 | 訂單綁定,表示訂單編號生效,進入貸款頁面,但尚未註冊,最後會在回傳狀態: A0002:消費者放棄該筆交易,該筆交易視同交易失敗,為最終結果 275:無卡分期-請等候審查通過 | |
| 270 | 交易成功 - 尚未付款完成,虛擬帳號-請等候消費者繳費入帳完成付款或消費者放棄交易,API會再傳送一次結果: 250:代表消費者付款成功,此為最終結果 380:代表消費者沒有在時限內去繳費,逾期未去繳費,視同交易失敗,此為最終結果 | |
| 275 | 交易成功 - 待審核(核貸中),無卡分期-請等候審查通過核貸或婉拒,API會再傳送一次結果: 250:代表該筆訂單已核貸,此為最終結果 380:代表該筆訂單沒有在時限內完成審核,視同交易失敗,此為最終結果 | |
| 280 | 交易成功 - 尚未付款完成,儲值/WEBATM-線上待付款,等待狀態,等到使用者線上完成交易後API會再傳送一次結果: 250:代表消費者付款成功,此為最終結果 300:代表消費者付款失敗 | |
| 282 | 訂單成立待審核,後支付,等待狀態,等到此筆訂單審核通過 | |
| 284 | 訂單成立待出貨,後支付,等待狀態,特約商店可以進行出貨 | |
| 290 | 交易成功 - 但資訊不符,包含金額不符、已逾期...等,該類型交易請特別注意 | |
| 300 | 交易失敗,金流服務商回傳交易失敗或該筆交易超過風險控管限制規則 | |
| 380 | 逾期交易,超商代碼或虛擬帳號交易,超過系統設定繳費期限,若經API查詢驗證後,有機會再變更狀態: 290:交易成功,但資訊不符,原因有可能是服務商的參數規則漏洞或是系統時間差異造成 | |
| 400 | 系統錯誤訊息,若API或上游服務商系統異常時 | |
| 600 | 結帳完成,API視為付款完成,此狀態為上游服務商確認訂單後的狀態,表示該筆訂單會撥款,透過MYPAY主動查詢或每日對帳機制,操作訂單功能內發動查詢功能 | |
| A0001 | 交易待確認,API與金流服務商發生連線異常,待查詢後確認結果,會主動再次回傳交易結果: 250:代表消費者確實付款完成 600:結帳完成 300:金流服務商回傳交易失敗或超過風險控管限制規則交易 | |
| A0002 | 放棄交易,畫面導向API後,消費者即放棄該筆交易,該筆交易視同交易失敗,為最終結果 | |
| B200 | 執行成功,API處理成功執行 | |
| B500 | 執行失敗,API處理時,資料異常不予以處理 |
App回傳碼說明
注意︰
- 202 ~ 205的成功碼原本在錯誤碼時,AppReponse只會有code和msg,並不會有交易成功的資訊,在改為成功碼之後,會在AppResponse回傳對應的交易與發票資訊,讓串接方可以同步交易的狀態,但後續的處理則必須由人員介入,如補印簽單、發票等。
- 而9999_2、9999_3、9999_11、9999_13這些錯誤碼將棄用,並由對應的成功碼去取代(不會向下相容),串接方必須對這些回傳碼進行處理,以確保取得完整的交易資訊。
| 回傳碼 | 說明 | 備註 |
|---|---|---|
| 200 | App執行動作成功,如掃碼成功與列印成功等 | |
| 201 | 切換使用者成功,表示此次的登入為切換使用者的情況,且登入成功 | |
| 202 | 交易成功,列印失敗,此表示交易成功,只需重新列印缺少的單據,無須重新交易 | 原本對應之錯誤碼為9999_2:交易成功,列印失敗 |
| 203 | 退款成功,列印失敗,此表示退款成功,只需重新列印缺少的單據,無須重新交易 | 原本對應之錯誤碼為9999_3:退款成功,列印失敗 |
| 204 | 交易成功,發票配號失敗,此表示交易成功,但設備上無可用的發票號碼,必須手動取號後再開立發票 | 原本對應之錯誤碼為9999_11:交易成功,發票配號失敗 |
| 205 | 交易成功,開立發票失敗,此表示交易成功,但發票系統因未知的情況產生錯誤導致無法開立發票,必須等到發票系統正常後,再到對應的交易明細頁中進行發票資訊的同步 | 原本對應之錯誤碼為9999_13:交易成功,開立發票失敗 |
| 9999 | 非預期的錯誤,為非正常流程產生之錯誤,如讀卡失敗或程式處理不當,訊息通常為Exception的Message | 若收到此錯誤時,請協助回報使用流程與是否能重現該錯誤 |
| 9999_x | MYPAY APP錯誤︰ 9999_1:使用者取消動作 9999_4:交易中斷 9999_5:查詢的交易不存在 9999_6:取消登入(39Buy) 9999_7:掃碼錯誤 9999_8:取消感應票卡 9999_9:尚未設定合作夥伴的URL 9999_10:請先安裝xxx APP 9999_12:一碼付切換使用者 | 此部分的錯誤請依對應的情況進行處理︰ 9999_1:此動作為使用者自行決定的動作,即手動取消,如果已發動交易,MYPAY APP將會在背景進行退款動作,以避免同一訂單進行多次交易的情況發生 9999_4:MYPAY APP將會在背景進行退款動作,以避免同一訂單進行多次交易的情況發生 |
一卡通回傳碼說明
| 回傳碼 | 說明 | 備註 |
|---|---|---|
| 0000 | 執行正確 | |
| 8000 | 設備異常報修 | |
| 8001 | 設備異常報修 | |
| 8002 | 設備異常報修 | |
| 8003 | 設備異常報修 | |
| 8004 | 設備異常報修 | |
| 8005 | 設備異常報修 | |
| 8006 | 設備異常報修 | |
| 8007 | 設備異常報修 | |
| 8008 | 設備異常報修 | |
| 8009 | 設備異常報修 | |
| 800A | 設備異常報修 | |
| 800B | 設備異常報修 | |
| 800C | 設備異常報修 | |
| 800D | 設備異常報修 | |
| 800E | 設備異常報修 | |
| 800F | 偵測不到票卡 | |
| 8010 | 設備異常報修 | |
| 8011 | 多卡無法交易 | |
| 8030 | 設備異常報修 | |
| 8031 | 設備異常報修 | |
| 8032 | 設備異常報修 | |
| 8040 | 設備異常報修 | |
| 8041 | 設備異常報修 | |
| 8050 | 設備異常報修 | |
| 8051 | 設備異常報修 | |
| 8052 | 設備異常報修 | |
| 8060 | 設備異常報修 | |
| 8061 | 設備異常報修 | |
| 8062 | 設備異常報修 | |
| 8063 | 設備異常報修 | |
| 8080 | 設備異常報修 | |
| 8081 | 設備異常報修 | |
| 8082 | 設備異常報修 | |
| 8083 | 設備異常報修 | |
| 8084 | 設備異常報修 | |
| 8085 | 設備異常報修 | |
| 8086 | 設備異常報修 | |
| 8087 | 設備異常報修 | |
| 8088 | 設備異常報修 | |
| 8089 | 設備異常報修 | |
| 808A | 設備異常報修 | |
| 808B | 設備異常報修 | |
| 808C | 設備異常報修 | |
| 808D | 設備異常報修 | |
| 808E | 設備異常報修 | |
| 808F | 設備異常報修 | |
| 8090 | 設備異常報修 | |
| 8091 | 設備異常報修 | |
| 8092 | 設備異常報修 | |
| 8093 | 設備異常報修 | |
| 8094 | 設備異常報修 | |
| 8095 | 設備異常報修 | |
| 8096 | 設備異常報修 | |
| 8097 | 設備異常報修 | |
| 8098 | 設備異常報修 | |
| 8099 | 設備異常報修 | |
| 809A | 設備異常報修 | |
| 809B | 設備異常報修 | |
| 809C | 設備異常報修 | |
| 809D | 設備異常報修 | |
| 809E | 設備異常報修 | |
| 8100 | 讀卡失敗重試 | |
| 8101 | 讀卡失敗重試 | |
| 8102 | 讀卡失敗重試 | |
| 8103 | 讀卡失敗重試 | |
| 8104 | 讀卡失敗重試 | |
| 8105 | 讀卡失敗重試 | |
| 8106 | 讀卡失敗重試 | |
| 8107 | 讀卡失敗重試 | |
| 8108 | 讀卡失敗重試 | |
| 8109 | 讀卡失敗重試 | |
| 810A | 讀卡失敗重試 | |
| 810B | 讀卡失敗重試 | |
| 810C | 寫卡失敗重試 | |
| 810D | 設備損壞報修 | |
| 810E | 寫卡失敗重試 | |
| 810F | 寫卡失敗重試 | |
| 8110 | 寫卡失敗重試 | |
| 8111 | 寫卡失敗重試 | |
| 8112 | 錯誤發卡單位 | |
| 8113 | 票卡效期逾期 | |
| 8114 | 票卡版本錯誤 | |
| 8115 | 票卡已鎖卡 | |
| 8116 | 票卡狀態錯誤 | |
| 8117 | 票卡資料異常 | |
| 8118 | 身分效期逾期 | |
| 8119 | 非消費類票卡 | |
| 811A | 票值格式錯誤 | |
| 811B | 票值格式錯誤 | |
| 811C | 票值格式錯誤 | |
| 811D | 交易金額錯誤 | |
| 811E | 超過單筆上限 | |
| 811F | 超過當日上限 | |
| 8120 | 票卡餘額不足 | |
| 8121 | 超過餘額上限 | |
| 8122 | 非原交易票卡 | |
| 8123 | 加值金額異常 | |
| 8124 | 無法自動加值 | |
| 8125 | 票卡資料異常 | |
| 8126 | 餘額高於門檻 | |
| 8127 | 載入金鑰失敗 | |
| 8130 | 非社福類票卡 | |
| 8131 | 社福單位不符 | |
| 8132 | 社福識別不符 | |
| 8134 | 社福點數不足 | |
| 8135 | 超過點數上限 | |
| 8136 | 錯誤交易請求 | |
| 8137 | 無效的票卡 | |
| 8138 | 無效企業代碼 | |
| 8139 | 無效識別單位 | |
| 8140 | 無效識別身分 | |
| 8180 | 讀卡失敗重試 | |
| 8181 | 讀卡失敗重試 | |
| 8182 | 讀卡失敗重試 | |
| 8183 | 讀卡失敗重試 | |
| 8184 | 讀卡失敗重試 | |
| 8185 | 讀卡失敗重試 | |
| 8186 | 讀卡失敗重試 | |
| 8187 | 讀卡失敗重試 | |
| 8188 | 讀卡失敗重試 | |
| 8189 | 讀卡失敗重試 | |
| 818A | 讀卡失敗重試 | |
| 818B | 讀卡失敗重試 | |
| 818C | 讀卡失敗重試 | |
| 818D | 讀卡失敗重試 | |
| 818E | 讀卡失敗重試 | |
| 818F | 讀卡失敗重試 | |
| 8190 | 讀卡失敗重試 | |
| 8191 | 讀卡失敗重試 | |
| 8192 | 讀卡失敗重試 | |
| 8193 | 讀卡失敗重試 | |
| 8194 | 讀卡失敗重試 | |
| 8195 | 讀卡失敗重試 | |
| 8196 | 讀卡失敗重試 | |
| 8197 | 讀卡失敗重試 | |
| 8198 | 讀卡失敗重試 | |
| 8199 | 讀卡失敗重試 | |
| 819A | 讀卡失敗重試 | |
| 819B | 讀卡失敗重試 | |
| 819C | 讀卡失敗重試 | |
| 819D | 讀卡失敗重試 | |
| 819E | 讀卡失敗重試 | |
| 819F | 讀卡失敗重試 | |
| 81A0 | 讀卡失敗重試 | |
| 81A1 | 讀卡失敗重試 | |
| 81A2 | 讀卡失敗重試 | |
| 81A3 | 讀卡失敗重試 | |
| 81A4 | 讀卡失敗重試 | |
| 81A5 | 讀卡失敗重試 | |
| 81A6 | 讀卡失敗重試 | |
| 81A7 | 讀卡失敗重試 | |
| 81A8 | 讀卡失敗重試 | |
| 81A9 | 讀卡失敗重試 | |
| 81AA | 讀卡失敗重試 | |
| 81AB | 讀卡失敗重試 | |
| 81AC | 讀卡失敗重試 | |
| 81AD | 讀卡失敗重試 | |
| 81AE | 讀卡失敗重試 | |
| 81AF | 讀卡失敗重試 | |
| 81B0 | 讀卡失敗重試 | |
| 81B1 | 讀卡失敗重試 | |
| 81B2 | 讀卡失敗重試 | |
| 81BF | 讀卡失敗重試 | |
| 81C0 | 寫卡失敗重試 | |
| 81C1 | 寫卡失敗重試 | |
| 81C2 | 寫卡失敗重試 | |
| 81C3 | 寫卡失敗重試 | |
| 81C4 | 寫卡失敗重試 | |
| 81C5 | 寫卡失敗重試 | |
| 81C6 | 寫卡失敗重試 | |
| 81C7 | 寫卡失敗重試 | |
| 81C8 | 寫卡失敗重試 | |
| 81C9 | 寫卡失敗重試 | |
| 81CA | 寫卡失敗重試 | |
| 81CB | 寫卡失敗重試 | |
| 81CC | 寫卡失敗重試 | |
| 81CD | 寫卡失敗重試 | |
| 81CE | 寫卡失敗重試 | |
| 81CF | 寫卡失敗重試 | |
| 81D0 | 寫卡失敗重試 | |
| 81D1 | 寫卡失敗重試 | |
| 81D2 | 寫卡失敗重試 | |
| 81D3 | 寫卡失敗重試 | |
| 81D4 | 寫卡失敗重試 | |
| 81D5 | 寫卡失敗重試 | |
| 81D6 | 寫卡失敗重試 | |
| 81D7 | 寫卡失敗重試 | |
| 81D8 | 寫卡失敗重試 | |
| 81D9 | 寫卡失敗重試 | |
| 81DA | 寫卡失敗重試 | |
| 81DB | 寫卡失敗重試 | |
| 81DC | 寫卡失敗重試 | |
| 81DD | 寫卡失敗重試 | |
| 81DE | 寫卡失敗重試 | |
| 81DF | 寫卡失敗重試 | |
| 81E0 | 寫卡失敗重試 | |
| 81E1 | 寫卡失敗重試 | |
| 81E2 | 寫卡失敗重試 | |
| 81E3 | 寫卡失敗重試 | |
| 81E4 | 寫卡失敗重試 | |
| 81E5 | 寫卡失敗重試 | |
| 81E6 | 寫卡失敗重試 | |
| 81E7 | 寫卡失敗重試 | |
| 81E8 | 寫卡失敗重試 | |
| 81E9 | 寫卡失敗重試 | |
| 81EA | 寫卡失敗重試 | |
| 81EB | 寫卡失敗重試 | |
| 81EC | 寫卡失敗重試 | |
| 81ED | 寫卡失敗重試 | |
| 81EE | 寫卡失敗重試 | |
| 81EF | 寫卡失敗重試 | |
| 81F0 | 寫卡失敗重試 | |
| 81F1 | 寫卡失敗重試 | |
| 81F2 | 寫卡失敗重試 | |
| 81FF | 寫卡失敗重試 | |
| 8200 | 時間錯誤報修 | |
| 8201 | 變數錯誤報修 | |
| 8202 | 檔案錯誤報修 | |
| 8203 | 檔案錯誤報修 | |
| 8204 | 檔案錯誤報修 | |
| 8205 | 檔案錯誤報修 | |
| 8206 | 檔案錯誤報修 | |
| 8207 | 檔案錯誤報修 | |
| 8208 | 檔案錯誤報修 | |
| 8210 | 格式錯誤報修 | |
| 8240 | 網路傳輸錯誤 | |
| 8241 | 網路傳輸錯誤 | |
| 8242 | 網路傳輸錯誤 | |
| 8243 | 網路傳輸錯誤 | |
| 8244 | 網路傳輸錯誤 | |
| 8280 | 網路傳輸錯誤 | |
| 8281 | 網路傳輸錯誤 | |
| 8282 | 網路傳輸錯誤 | |
| 8283 | 網路傳輸錯誤 | |
| 8284 | 網路傳輸錯誤 | |
| 8285 | 網路傳輸錯誤 | |
| 8286 | 網路傳輸錯誤 | |
| 8287 | 網路傳輸錯誤 | |
| 82C0 | 網路傳輸錯誤 | |
| 82C1 | 網路傳輸錯誤 | |
| 82C2 | 網路傳輸錯誤 | |
| 82C3 | 網路傳輸錯誤 | |
| 82C4 | 網路傳輸錯誤 | |
| 82C5 | 網路傳輸錯誤 | |
| 82C6 | 網路傳輸錯誤 | |
| 82C7 | 網路傳輸錯誤 | |
| 82C8 | 網路傳輸錯誤 | |
| 82C9 | 網路傳輸錯誤 | |
| 82CA | 網路傳輸錯誤 | |
| 82CB | 網路傳輸錯誤 | |
| 8300 | 交易授權失敗 | |
| 8301 | 交易授權失敗 | |
| 8302 | 交易授權失敗 | |
| 8303 | 註冊異常報修 | |
| 8304 | 票卡進行鎖卡 | |
| 8305 | 交易授權失敗 | |
| 8306 | 銀行授權失敗 | |
| 8307 | 交易授權失敗 | |
| 8308 | 交易授權失敗 | |
| 8309 | 交易授權失敗 | |
| 830A | 交易授權失敗 | |
| 830B | 設備時間異常 | |
| 830C | 無此交易功能 | |
| 830D | 交易授權失敗 | |
| 830E | 票卡資格錯誤 | |
| 830F | 交易授權失敗 | |
| 8310 | 交易授權失敗 | |
| 8311 | 交易授權失敗 | |
| 8312 | 交易授權失敗 | |
| 8313 | 交易重複失敗 | |
| 8314 | 交易授權失敗 | |
| 8315 | 交易授權失敗 | |
| 8316 | 交易授權失敗 | |
| 8317 | 交易授權失敗 | |
| 8318 | 交易授權失敗 | |
| 8319 | 交易授權失敗 | |
| 831A | 交易授權失敗 | |
| 831B | 交易授權失敗 | |
| 831C | 交易授權失敗 | |
| 831D | 交易授權失敗 | |
| 831E | 交易授權失敗 | |
| 831F | 交易授權失敗 | |
| 8320 | 交易授權失敗 | |
| 8321 | 交易授權失敗 | |
| 8322 | 交易授權失敗 | |
| 8323 | 交易授權失敗 | |
| 8324 | 交易授權失敗 | |
| 8325 | 交易授權失敗 | |
| 8326 | 交易授權失敗 | |
| 8327 | 交易授權失敗 | |
| 8328 | 需清除系統檔 | |
| 8329 | 已創立新業者 | |
| 832A | 交易授權失敗 | |
| 832B | 交易授權失敗 | |
| 832C | 交易授權失敗 | |
| 832D | 交易授權失敗 | |
| 832E | 交易授權失敗 | |
| 832F | 交易授權失敗 | |
| 8330 | 交易授權失敗 | |
| 8331 | 交易授權失敗 | |
| 8332 | 交易授權失敗 | |
| 8333 | 帳戶額度不足 | |
| 8334 | 交易授權失敗 | |
| 8335 | 交易授權失敗 | |
| 8336 | 交易授權失敗 | |
| 8337 | 交易授權失敗 | |
| 8338 | 交易授權失敗 | |
| 8339 | 交易授權失敗 | |
| 833A | 交易授權失敗 | |
| 833B | 交易授權失敗 | |
| 833C | 交易授權失敗 | |
| 833D | 交易授權失敗 | |
| 833E | 交易授權失敗 | |
| 833F | 交易授權失敗 | |
| 8340 | 交易授權失敗 | |
| 8341 | 交易授權失敗 | |
| 8342 | 交易授權失敗 | |
| 8343 | 交易授權失敗 | |
| 8344 | 交易授權失敗 | |
| 8345 | 交易授權失敗 | |
| 8346 | 交易授權失敗 | |
| 8347 | 交易授權失敗 | |
| 8348 | 交易授權失敗 | |
| 8349 | 交易授權失敗 | |
| 834A | 交易授權失敗 | |
| 834B | 交易授權失敗 | |
| 834C | 交易授權失敗 | |
| 834D | 交易授權失敗 | |
| 834E | 交易授權失敗 | |
| 834F | 交易授權失敗 | |
| 8350 | 交易授權失敗 | |
| 8351 | 交易授權失敗 | |
| 8352 | 交易授權失敗 | |
| 8353 | 交易授權失敗 | |
| 8354 | 交易授權失敗 | |
| 8355 | 交易授權失敗 | |
| 8356 | 交易授權失敗 | |
| 8357 | 交易授權失敗 | |
| 8358 | 交易授權失敗 | |
| 8359 | 交易授權失敗 | |
| 835A | 系統滿載中 | |
| 835B | 授權主機異常 | |
| 835C | 授權主機異常 | |
| 835D | 交易授權失敗 | |
| 835E | 授權主機異常 | |
| 835F | 結班不平帳 | |
| 8360 | 授權主機異常 | |
| 8361 | 授權主機異常 | |
| 8362 | 交易授權失敗 | |
| 8363 | 交易授權失敗 | |
| 8380 | 網路簽章錯誤 | |
| 8381 | 網路簽章錯誤 | |
| 8382 | 網路簽章錯誤 | |
| 8383 | 網路簽章錯誤 | |
| 8384 | 網路簽章錯誤 | |
| 8385 | 網路簽章錯誤 | |
| 8386 | 網路簽章錯誤 | |
| 8387 | 網路簽章錯誤 | |
| 8388 | 網路簽章錯誤 | |
| 8389 | 網路簽章錯誤 | |
| 838A | 網路簽章錯誤 | |
| 838B | 網路簽章錯誤 | |
| 838C | 網路簽章錯誤 | |
| 838D | 網路簽章錯誤 | |
| 838E | 網路簽章錯誤 | |
| 838F | 網路簽章錯誤 | |
| 8390 | 沖正尚未傳送 | |
| 8391 | 沖正操作失敗 | |
| 8392 | 上傳紀錄失敗 | |
| 83C0 | 交易成功報修 | |
| 83C1 | 交易成功報修 | |
| 83C2 | 票卡已鎖卡 | |
| 83C3 | 交易紀錄未傳 | |
| 83C4 | 查無對應交易 | |
| 83C5 | 沖正尚未傳送 | |
| 83C6 | 沖正傳送完成 | |
| 83C7 | 尚未端末開機 | |
| 83C8 | 完成端末開機 | |
| 83C9 | 業者密碼錯誤 | |
| 83CA | 檔案錯誤報修 | |
| 83CB | 交易格試錯誤 | |
| 83CC | 錯誤交易類型 | |
| 83CD | 錯誤交易請求 | |
| 83CE | 尚未端末開機 | |
| 83CF | 尚未結班 | |
| 83D0 | 請把票卡放回 | |
| 83D1 | 交易成功報修 | |
| 83D2 | 重複交易 | |
| 83E0 | 錯誤交易類別 | |
| 8400 | 加值失敗 | |
| 8800 | 輸入格式錯誤 | |
| 8801 | 輸入長度錯誤 | |
| 8802 | 輸入命令錯誤 | |
| 8803 | 輸入BCC錯誤 | |
| 8804 | 輸入內容錯誤 | |
| 8810 | 輸出內容錯誤 | |
| 8830 | 位址轉IP錯誤 | |
| 8831 | 交易失敗 | |
| 8832 | 交易失敗 | |
| 8833 | 交易失敗 | |
| 8834 | 交易失敗 | |
| 8840 | 電文傳送中止 | |
| 8841 | 電文傳送中止 | |
| 6000 | 金鑰錯誤 | |
| 6FFF | 金鑰錯誤 |
39Buy查詢Request共同欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | page | 頁數 | int | 預設1 |
| 2 | perPage | 每頁筆數 | string | 預設10,輸入all就是全部 |
| 3 | keyword | 名稱搜尋關鍵字 | string |
39Buy新增修改產品Request共同欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | productNo | 產品編號 | string | 非必要,如果未給值,系統將自動產生新的編號 |
| 2 | productClass | 所屬關聯分類資料,只需要上層的id即可 | string array | |
| 3 | productType | 產品規格︰ 1=單規格 2=雙規格 3=三規格 99=無規格 | int | 預設99 |
| 4 | zhTwName | 繁體產品名稱 | string | 繁體、英文、簡體三種語系必須選填一個 |
| 5 | enUsName | 英文產品名稱 | string | 繁體、英文、簡體三種語系必須選填一個 |
| 6 | zhCnName | 簡體產品名稱 | string | 繁體、英文、簡體三種語系必須選填一個 |
| 7 | productSwitch | 產品狀態︰ 0=未開放購買 1=開放購買 2=草稿 3=結案 | int | 預設1 |
| 8 | startOpenDate | 開放產品可購買開始時間,格式為yyyy-MM-dd HH:mm:ss | string | 必要 |
| 9 | endOpenDate | 開放產品可購買結束時間,格式為yyyy-MM-dd HH:mm:ss | string | |
| 10 | payMode | 產品可用付款方式 | string | 必要,各付款方式以逗號(,)隔開,請參考付款方式說明 |
| 11 | textPeriod | 定期定額周期選項 | string | |
| 12 | regularTotal | 定期定額指定期數 | string | |
| 13 | tags | 產品標籤,帶入標籤名稱 | string array | |
| 14 | zhTwProductDesc | 產品簡短說明(繁中) | string | |
| 15 | enUsProductDesc | 產品簡短說明(英文) | string | |
| 16 | zhCnProductDesc | 產品簡短說明(簡中) | string | |
| 17 | zhTwPageDesc | 頁面說明(繁中) | string | |
| 18 | enUsPageDesc | 頁面說明(英文) | string | |
| 19 | zhCnPageDesc | 頁面說明(簡中) | string | |
| 20 | imgData | 產品圖片 | list | 請參考39Buy產品圖片欄位說明 |
| 21 | shippingFeeTaiwan | 台灣宅配運費 | string | 預設0 |
| 22 | freeShippingTaiwan | 台灣宅配免運門檻 | string | 預設0 |
| 23 | shippingFeeIsland | 台灣離島宅配運費 | string | 預設0 |
| 24 | freeShippingIsland | 台灣離島宅配免運門檻 | string | 預設0 |
| 25 | shippingFeeChina | 大陸宅配運費 | string | 預設0 |
| 26 | freeShippingChina | 大陸宅配免運門檻 | string | 預設0 |
| 27 | shippingFeeOversea | 海外宅配運費 | string | 預設0 |
| 28 | freeShippingOversea | 海外宅配免運門檻 | string | 預設0 |
| 29 | buyerInfo | 購買該產品時買家的必要欄位︰ name=姓名 phone=電話 address=地址 mail=e-mail query_code=查詢碼 single_number=自取碼 memo=備註 payer_id=身份證字號 | string | 各欄位以逗號(,)隔開 |
| 30 | pickUpType | 取貨方式︰ 0=無須取貨 1=宅配 2=自取 4=取貨付款 | string | 預設0,以逗號(,)隔開 |
| 31 | enforceBuyPieces | 強制購買數量 | int | |
| 32 | price | 產品定價 | string | 必要 |
| 33 | specialPrice | 產品售價 | string | 必要 |
| 34 | isReciprocal | 是否開放倒數計數︰ 0=否 1=是 | int | 預設0 |
| 35 | salesRepId | 綁定銷售人員 | string array |
39Buy修改產品Request共同欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | uid | 對應該產品的uid | string | 必要 |
| 2 | deleteProductClass | 刪除關聯分類資料的uid | string array | |
| 3 | deleteTags | 欲刪除的標籤uid | string array | |
| 4 | deleteImgIds | 欲刪除的產品圖id | string array | |
| 5 | deleteSpecUids | 要刪除的商品副檔uid | string array | |
| 6 | enforce | 檢查更新設定︰ 0=不強制 1=強制 | int | 預設0,系統會檢查五分鐘內是否有人異動過,如果不檢查請帶1強制更新,如果未帶,一律檢查,如5分鐘內有人異動過,則回應警告訊息 |
39Buy產品圖片欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | type | 資料類型︰ 1=上傳圖片:jpg、jpeg、png、gif 2=YouTube影片 3=圖片連結:限能用img src的URL 4=mp4、webm、ogg格式影片URL | int | 必要 |
| 2 | data | 資料︰ 1=使請用Base64格式 2=請使用YouTube網址尾碼 3=請使用完整URL 4=請使用完整URL | string | 必要,且對應資料類型 |
| 3 | description | 圖片描述 | string |
39Buy產品規格欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | erpNo | ERP料號,對應當有內部料號,作為產品販賣時的對應 | string | |
| 2 | seqNo | 規格排序 | int | 必要,請由數字1開始,如果重複,在抓取資料時,會按照異動時間排序 |
| 3 | spec1Code | 規格1代碼 | string | 依產品規格填寫 |
| 4 | spec2Code | 規格2代碼 | string | 依產品規格填寫 |
| 5 | spec3Code | 規格3代碼 | string | 依產品規格填寫 |
| 6 | spec1CodeZhTwName | 規格1繁體名稱 | string | 依產品規格填寫 |
| 7 | spec1CodeZhCnName | 規格1簡體名稱 | string | 依產品規格填寫 |
| 8 | spec1CodeEnUsName | 規格1英文名稱 | string | 依產品規格填寫 |
| 9 | spec2CodeZhTwName | 規格2繁體名稱 | string | 依產品規格填寫 |
| 10 | spec2CodeZhCnName | 規格2簡體名稱 | string | 依產品規格填寫 |
| 11 | spec2CodeEnUsName | 規格2英文名稱 | string | 依產品規格填寫 |
| 12 | spec3CodeZhTwName | 規格3繁體名稱 | string | 依產品規格填寫 |
| 13 | spec3CodeZhCnName | 規格3簡體名稱 | string | 依產品規格填寫 |
| 14 | spec3CodeEnUsName | 規格3英文名稱 | string | 依產品規格填寫 |
| 15 | price | 定價 | string | 預設為主檔price |
| 16 | specialPrice | 售價 | string | 預設為主檔specialPrice |
| 17 | stockEnable | 庫存是否啟用︰ 0=disable 1=enable | int | 預設0 |
| 18 | stock | 庫存 | int | 預設0 |
| 19 | priceLimitMode | 額度模式︰ 1=定額 2=不定額 | int | 預設1 |
| 20 | priceLimitMin | 不定額情況下,最小額度是多少,如果為0,代表不限制 | string | 預設0 |
39Buy超渡產品規格欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 產品規格欄位 | 產品規格的欄位 | 請參考39Buy產品規格欄位說明 | |
| 2 | ghostFestivalType | 超渡類型︰ 1=個別往生者 2=歷代祖先 3=寵物 4=地基主 5=嬰靈 6=冤親債主 7=其他 | int | 必要 |
| 3 | birthdayType | 生日是否強制必填︰ 0=否 1=是 | int | 預設0 |
| 4 | dieDayType | 歿日是否強制必填︰ 0=否 1=是 | int | 預設0 |
39Buy產品明細規格欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | uid | 產品副檔uid | string | |
| 2 | productNo | 產品編號 | string | |
| 3 | serialNo | 產品序號 | string | |
| 4 | erpNo | ERP料號,對應當有內部料號,作為產品販賣時的對應 | string | |
| 5 | seqNo | 規格排序 | int | |
| 6 | spec1Code | 規格1代碼 | string | |
| 7 | spec2Code | 規格2代碼 | string | |
| 8 | spec3Code | 規格3代碼 | string | |
| 9 | spec1CodeZhTwName | 規格1繁體名稱 | string | |
| 10 | spec1CodeZhCnName | 規格1簡體名稱 | string | |
| 11 | spec1CodeEnUsName | 規格1英文名稱 | string | |
| 12 | spec2CodeZhTwName | 規格2繁體名稱 | string | |
| 13 | spec2CodeZhCnName | 規格2簡體名稱 | string | |
| 14 | spec2CodeEnUsName | 規格2英文名稱 | string | |
| 15 | spec3CodeZhTwName | 規格3繁體名稱 | string | |
| 16 | spec3CodeZhCnName | 規格3簡體名稱 | string | |
| 17 | spec3CodeEnUsName | 規格3英文名稱 | string | |
| 18 | price | 定價 | string | |
| 19 | specialPrice | 售價 | string | |
| 20 | stockEnable | 庫存是否啟用︰ 0=disable 1=enable | int | |
| 21 | stock | 庫存 | int | |
| 22 | createdAt | 建立時間 | int | |
| 23 | updatedAt | 修改時間 | int |
39Buy產品明細圖片欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | uid | 圖片uid | string | |
| 2 | type | 資料類型︰ 1=上傳圖片:jpg、jpeg、png、gif 2=YouTube影片 3=圖片連結:限能用img src的URL 4=mp4、webm、ogg格式影片URL | int | 必要 |
| 3 | data | 資料︰ 1=使請用Base64格式 2=請使用YouTube網址尾碼 3=請使用完整URL 4=請使用完整URL | string | 必要,且對應資料類型 |
| 4 | description | 圖片描述 | string |
39Buy交易Request共同欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | designatePayMode | 交易模式代號︰ 1=信用卡 10=支付寶線上 13=微信支付線上 15=LINE Pay線上 27=Pi 拍錢包線上 31=街口支付線上 37=現金 98=所有線下交易 | string | 必要 |
| 2 | printMode | 列印模式︰ 2=發票 | String | 必要 |
| 3 | creditCardReceiptType | 信用卡簽單類型︰ 1=列印全部(商店存根&持卡人存根) 2=只印持卡人存根 | string | 當designatePayMode=1時必要 |
| 4 | queryCode | 訂單查詢碼 | string | |
| 5 | singleNumber | 自取碼 | string | |
| 6 | memo | 買家備註 | string | |
| 7 | currency | 交易幣別︰ TWD=新台幣 CNY=人民幣 | string | 必要 |
| 8 | customer | 消費者資料 | object | 請參考消費者資料欄位說明 |
| 9 | invoice | 發票資料 | object | 請參考發票資料欄位說明 |
| 10 | echo | echo資料 | object | 請參考echo欄位說明 |
39Buy慈善交易Request共同欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | 39Buy交易Request共同欄位 | 39Buy交易Request的共同欄位 | 請參考39Buy交易Request共同欄位說明 | |
| 2 | payerBirthdayType | 付款者生日類型︰ 1=國曆 2=農曆 | int | 預設1 |
| 3 | payerBirthdayTime | 付款者生辰(00 ~ 23) | string | 如果不知生日期間,請統一帶99 |
| 4 | payerLeap | 付款者生辰是否為閏月︰ 0=否 1=是 | int | 預設0 |
| 5 | letterOfThanksMail | 感謝信收件人mail | string | |
| 6 | letterOfThanksName | 感謝信收件人姓名 | string | |
| 7 | letterOfThanksPhoneCode | 感謝信收件人電話國碼 | string | |
| 8 | letterOfThanksPhone | 感謝信收件人電話 | string | |
| 9 | letterOfThanksZipCode | 感謝信收件人郵遞區號 | string | |
| 10 | letterOfThanksCountry | 感謝信收件人國籍 | string | |
| 11 | letterOfThanksCity | 感謝信收件人居住城市 | string | |
| 12 | letterOfThanksDistrict | 感謝信收件人居住區域 | string | |
| 13 | letterOfThanksAddress | 感謝信收件人地址 | string |
39Buy點燈名單欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | name | 點燈者名稱 | string | |
| 2 | birthdayType | 點燈者生日類型︰ 1=國曆 2=農曆 | int | 預設1 |
| 3 | birthday | 點燈者生日,格式為yyyy-MM-dd | string | 如果不知生日時間,請統一帶9999-99-99 |
| 4 | birthdayTime | 點燈者生辰(00 ~ 23) | string | 如果不知生日期間,請統一帶99 |
| 5 | leap | 是否為閏月︰ 0=否 1=是 | int | 預設0 |
| 6 | zipCode | 點燈者郵遞區號 | string | |
| 7 | country | 點燈者國家 | string | |
| 8 | city | 點燈者居住城市 | string | |
| 9 | district | 點燈者居住區域 | string | |
| 10 | address | 點燈者地址 | string | |
| 11 | specData | 產品列表 | list | 必要,請參考39Buy交易產品欄位說明 |
39Buy交易產品欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | id | 產品編號 | string | |
| 2 | name | 產品名稱 | string | |
| 3 | price | 產品單價 | string | |
| 4 | specUid | 產品規格uid | string | |
| 5 | number | 產品數量 | int | |
| 6 | amount | 自訂額度 | string | 當規格為自訂額度時,才檢查此項目 |
39Buy產品分類列表欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | uid | 分類uid | string | |
| 2 | zhTwName | 分類繁中名稱 | string | |
| 3 | level | 層級 | int | |
| 4 | status | 是否啟用︰ 0=否 1=是 | int |
39Buy產品分類關聯欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | parentUid | 父層uid | string | 若為0,表示為最上層 |
| 2 | productClassUid | 子層uid | string |
39Buy產品欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | uid | 產品uid | string | |
| 2 | storeUid | 特約商店編號 | string | |
| 3 | productNo | 產品編號 | string | |
| 4 | productClass | 產品分類 | string array | |
| 5 | zhTwName | 繁體產品名稱 | string | |
| 6 | enUsName | 英文產品名稱 | string | |
| 7 | zhCnName | 簡體產品名稱 | string | |
| 8 | productSwitch | 產品狀態︰ 0=未開放購買 1=開放購買 2=草稿 3=結案 | int | |
| 9 | price | 產品定價 | string | |
| 10 | specialPrice | 產品售價 | string | |
| 11 | shortUrl | 產品短網址 | string |
39Buy產品資料異常訊息欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | productNo | 產品編號 | string | |
| 2 | serialNo | 產品序號 | string | |
| 3 | code | 錯誤代碼 | string |
39Buy訂單資料欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | uid | 39Buy系統產生訂單編號 | string | |
| 2 | storeOrderId | 特店帶入的訂單編號 | string | |
| 3 | orderDate | 訂單日期,格式為yyyy-MM-dd HH:mm:ss | string | |
| 4 | shippingFee | 運費 | string | |
| 5 | type | 交易類型 | int | 請參考39Buy訂單產品類型說明 |
| 6 | payMode | 付款方式 | int | 請參考付款方式說明 |
| 7 | payPrice | 消費金額 | string | |
| 8 | refundPayPrice | 退款金額 | string | |
| 9 | currencyCls | 幣別記錄 | string | |
| 10 | cardNo | 遮碼卡號 | string | |
| 11 | aCode | 授權碼 | string | |
| 12 | discount | 折扣金額 | string | |
| 13 | redeem | 紅利兌換比例 | string | |
| 14 | retCode | 付款狀態 | string | 請參考39Buy付款狀態說明 |
| 15 | refundRetCode | 退款狀態 | string | 請參考39Buy退款狀態說明 |
| 16 | pickupType | 取貨方式︰ 0=無須取貨 1=線上下單宅配送貨 2=線上下單自取 3=門市下單宅配 4=門市下單自取 | int | |
| 17 | pickupAvailable | 貨物狀態︰ 0=狀態 1=已出貨(ALL) 2=可取貨(店自取) 3=已取貨(店自取) 4=已送達(送貨) | int | |
| 18 | pickupDate | 交貨時間,格式為yyyy-MM-dd HH:mm:ss | string | |
| 19 | singleNumber | 貨運單號或取貨代碼 | string | |
| 20 | memo | 買家留言 | string | |
| 21 | queryCode | 訂單查詢碼 | string | |
| 22 | taxiCarNumber | 計程車車號 | string | |
| 23 | taxiLicensePlateNumber | 計程車車牌號碼 | string | |
| 24-28 | echo0 ~ ech4 | 自訂紀錄 | string | |
| 29 | invoice | 發票回應資料 | int, string | 請參考39Buy發票回應資料欄位說明 |
39Buy發票回應資料欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | invoiceRateType | 稅率類型︰ 0=無稅率 1=應稅 2=零稅率 3=免稅 | int | |
| 2 | invoiceInputType | 類型︰ 0=不開 1=雲端發票 2=發票捐贈 3=實體發票 4=外部發票 5=免用統一發票 6=農漁民收據 | int | |
| 3 | invoiceCloudType | 雲端發票類型︰ 2=手機條碼 3=自然人憑證條碼 4=以E-Mail寄送 | int | 類型為1才有作用 |
| 4 | invoiceMobileCode | 手機條碼 | string | 雲端發票類型為2才有作用 |
| 5 | invoiceNaturalPerson | 自然人憑證條碼(格式請自行驗證) | string | 雲端發票類型為3才有作用 |
| 6 | invoiceLoveCode | 愛心碼(格式請自行驗證) | string | 類型為2才有作用 |
| 7 | invoiceB2bId | 買受人發票統編(格式請自行驗證) | string | 類型為3才有作用 |
| 8 | invoiceB2bTitle | 發票抬頭 | string | 類型為3才有作用 |
| 9 | invoiceNo | 發票號碼 | string | |
| 10 | invoiceRandomNumber | 發票隨機碼 | string | |
| 11 | invoiceSellerBan | 發票賣方統編 | string | |
| 12 | invoiceTaxRate | 發票稅率 | string | |
| 13 | invoiceLeftQrcode | 發票左邊QR Cdoe | string | |
| 14 | invoiceRightQrcode | 發票右邊QR Cdoe | string | |
| 15 | invoiceMiddleBarcode | 發票中間BarCode | string | |
| 16 | invoiceDateTime | 發票開立時間,格式為yyyy-MM-dd HH:mm:ss | string | |
| 17 | invoiceTitleType | 發票標題類型︰ 0=無設定 1=文字 2=圖片URL | int | |
| 18 | invoiceTitle | 發票標題 | string |
39Buy付款狀態說明
| 付款狀態 | 說明 | 備註 |
|---|---|---|
| 0 | 等待付款 | |
| 1 | 金流確認中 | |
| 2 | 預產單模式 | |
| 3 | 交易取消 | |
| 4 | 付款成功 | |
| 5 | 交易失敗 | |
| 6 | 預期交易 | |
| 7 | 已撥款 |
39Buy退款狀態說明
| 退款狀態 | 說明 | 備註 |
|---|---|---|
| 0 | 未發動退貨 | |
| 1 | 退貨處理中 | |
| 2 | 退貨取消 | |
| 3 | 退貨已完成 |
39Buy訂單欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | uid | 訂單uid | string | |
| 2 | storeOrderId | 商店自定訂單id | string | |
| 3 | type | 產品類型 | int | 請參考39Buy訂單產品類型說明 |
| 4 | orderDate | 訂單日期 | string | |
| 5 | payPrice | 訂單金額 | string | |
| 6 | payMode | 付款方式 | int | |
| 7 | retCode | 付款狀態 | string | 請參考39Buy付款狀態說明 |
| 8 | refundRetCode | 退款狀態 | string | 請參考39Buy退款狀態說明 |
| 9 | payerName | 付款人姓名 | string | |
| 10 | payerPhoneCode | 付款人手機國碼 | string | |
| 11 | payerPhone | 付款人手機號碼 | string | |
| 12 | payerMail | 付款人email | string | |
| 13 | queryCode | 訂單查詢碼 | string | |
| 14 | letterOfThanksMail | 感謝信收件人mail | string | |
| 15 | letterOfThanksName | 感謝信收件人姓名 | string |
39Buy訂單產品細項欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | uid | 產品副檔uid | string | |
| 2 | orderUid | 訂單編號 | string | |
| 3 | productUid | 對應該訂單子項目的單元產品uid (mdes_products->uid),用在退貨時加回庫存 | string | |
| 4 | productNo | 產品編號 | string | |
| 5 | erpNo | 產品料號 | string | |
| 6 | serialNo | 產品序號 | string | |
| 7 | zhTwName | 產品名稱(繁中) | string | |
| 8 | enUsName | 產品名稱(簡中) | string | |
| 9 | zhCnName | 產品名稱(簡中) | string | |
| 10 | price | 產品單價 | string | |
| 11 | number | 訂購數量 | int | |
| 12 | startDate | 產品起始有效日 | string | |
| 13 | endDate | 產品結束有效日 | string | |
| 14 | contractGuaranteeStartDate | 履約擔保日期起 | string | |
| 15 | contractGuaranteeEndDate | 履約擔保日期迄 | string | |
| 16 | inputDetailInfo | 原始帶入的商品資訊JSON string | string | |
| 17 | productInfo | 轉成自己的產品格式JSON string,記錄相關產品資訊,因應立即購買的訂單類型 | string | |
| 18 | saleType | 商品類型︰ 1=商品 2=加購品 3=不限制 4=贈品 5=運費 6=全館活動折扣 7=折價劵 8=紅利點數 | int | |
| 19 | printOut | 用於通知是否顯示於收據明細︰ 0=不顯示 1=顯示 | int | |
| 20 | createdAt | 建立時間 | string | |
| 21 | updatedAt | 修改時間 | string | |
| 22 | refundStatus | 退貨狀態︰ 0=未退 1=已退 | int |
39Buy訂單付款資料欄位說明
| 項次 | 欄位 | 說明 | 型別 | 備註 |
|---|---|---|---|---|
| 1 | id | 流水號 | string | |
| 2 | orderUid | 訂單編號 | string | |
| 3 | keyUid | 購買編號-金流的交易編號(UID) | string | |
| 4 | storeToken | 次特店驗證碼 | string | |
| 5 | refundUid | 退款訂單流水號 | string | |
| 6 | charge | 單次扣款金額 | string | |
| 7 | orderState | 對應金流系統的訂單狀態 | string | |
| 8 | memo | 註解 | string | |
| 9 | payDate | 金流的付款日期 | string | |
| 10 | payMode | 付款方式 | string | |
| 11 | paymentName | 定期定額扣款名稱 | string | |
| 12 | nois | 定期定額期數 | string | |
| 13 | cost | 金額 | string | |
| 14 | feePrice | 交易手續費 | string | |
| 15 | refundFeePrice | 退款手續費 | string | |
| 16 | cardNo | 卡號 | string | |
| 17 | aCode | 授權碼 | string | |
| 18 | cardType | 信用卡類別︰ 0=無法辨識或支付方式為非信用卡類 1=VISA 2=MasterCard 3=JCB 4=AMEX | string | |
| 19 | issuingBank | 發卡行 | string | |
| 20 | issuingBankUid | 發卡銀行代碼 | string | |
| 21 | transactionMode | 交易服務類型︰ 0=尚未進行閘道交易 1=代收代付 2=特店模式 | string | |
| 22 | supplierName | 交易之金融服務商 | string | |
| 23 | supplierCode | 交易之金融服務商代碼 | string | |
| 24 | data | 回傳資料紀錄 | string | |
| 25 | createdAt | 建立時間 | string | |
| 26 | updatedAt | 修改時間 | string |
39Buy訂單產品類型說明
| 訂單產品類型 | 說明 | 備註 |
|---|---|---|
| 0 | 異常交易類型 | |
| 1 | 一般商品 | |
| 3 | 慈善捐款 | |
| 8 | 快速結帳 | |
| 10 | 一碼貸 | |
| 11 | TrCode | |
| 12 | 月費型商品 | |
| 13 | 票劵/課程類型商品 | |
| 14 | 訂單系統-發票 | |
| 15 | 訂單系統-明細 | |
| 16 | 點餐單 | |
| 17 | 慈善-點燈 | |
| 18 | 慈善-超渡 | |
| 19 | 任意付 |
39Buy回傳碼說明
| 回傳碼 | 說明 | 備註 |
|---|---|---|
| 0 | 執行成功 | |
| 100 | 串接基本資料錯誤 | |
| API_003 | 內部AP串接欄位錯誤 | |
| 200 | 登入成功,或資料正確,API收到正確資料 | |
| 500 | 登入失敗 | |
| 900 | Token無效,請重新登入系統 | |
| App回傳碼 | MYPAY APP處理錯誤的回傳碼 | 請參考App回傳碼說明 |
39Buy新增產品回傳碼說明
| 新增產品回傳碼 | 說明 | 備註 |
|---|---|---|
| 39Buy回傳碼 | 請參考39Buy回傳碼說明 | |
| A0000 | 新增成功 | |
| A0001 | 查無商品 | |
| A0002 | 商品名稱請擇一必填 | |
| A0003 | 商品類型必填 | |
| A0004 | 商品規格必填 | |
| A0005 | 商品起始時間規則錯誤 | |
| A0006 | 支付工具必填 | |
| A0007 | 商品起始時間必須大於結束時間 | |
| A0008 | 商品編號重複 | |
| A0009 | 規格代碼重複 | |
| A0010 | 規格代碼沒有填值 | |
| A0011 | 超渡類型不符 | |
| A9999 | 新增異常 |
39Buy修改產品回傳碼說明
| 修改產品回傳碼 | 說明 | 備註 |
|---|---|---|
| 39Buy回傳碼 | 請參考39Buy回傳碼說明 | |
| E0000 | 修改成功 | |
| E0001 | 5分鐘內有人異動,是否再度異動 | |
| E0002 | 查無商品 | |
| E0003 | 商品類型與原類型不同 | |
| E0004 | 商品名稱請擇一必填 | |
| E0005 | 商品類型必填 | |
| E0006 | 商品規格必填 | |
| E0007 | 商品起始時間規則錯誤 | |
| E0008 | 支付工具必填 | |
| E0009 | 修改者必填 | |
| E0010 | 商品起始時間必須大於結束時間 | |
| E0011 | 商品在5分鐘內已有修改過,不更新,如要強制更新,請調整強制更新參數 | |
| E9999 | 修改異常 |
39Buy交易回傳碼說明
| 交易回傳碼 | 說明 | 備註 |
|---|---|---|
| 39Buy回傳碼 | 請參考39Buy回傳碼說明 | |
| B0000 | 交易成功 | |
| B0001 | 商品已下架 | |
| B0002 | 商品庫存不足 | |
| B0003 | 查無商品 | |
| B0004 | 金額不符 | |
| B0005 | 沒有交易商品 | |
| B0006 | 小於最低額度 | |
| B0007 | 不支援此支付方式 | |
| B0008 | 付款人姓名未填寫 | |
| B0009 | 付款人電話未填寫 | |
| B0010 | 付款人地址未填寫 | |
| B0011 | 付款人E-mail未填寫 | |
| B0012 | 付款人訂單查詢碼未填寫 | |
| B0013 | 付款人訂單取貨碼未填寫 | |
| B0014 | 付款人備註未填寫 | |
| B0015 | 交易成功,等待消費者付款 | |
| B0016 | 查無此清單資訊 | |
| B0017 | 查無商店 | |
| B0018 | 大特店商務代號錯誤 | |
| B0019 | 此清單中不含有此商品 | |
| B0020 | 清單活動異常設定,折扣金額大於結帳金額 | |
| B9997 | 驗證無誤,可以執行交易 | |
| B9998 | 交易異常,請15分鐘後重新查詢交易結果 | |
| B9999 | 交易失敗 |
付款類型說明(對應付款方式)
| 付款類型 | 說明 | 備註 |
|---|---|---|
| CREDITCARD | 信用卡 | 1 |
| ABROAD | 海外信用卡 | 9 |
| ALIPAY | 支付寶線上 | 10 |
| 微信支付線上 | 13 | |
| WECHATOFF | 微信支付線下 | 19 |
| LINEPAYON | LINE Pay線上 | 15 |
| LINEPAYOFF | LINE Pay線下 | 16 |
| PION | Pi 拍錢包線上 | 27 |
| PIOFF | Pi 拍錢包線下 | 28 |
| JKOON | 街口支付線上 | 31 |
| JKOOFF | 街口支付線下 | 32 |
| CASH | 現金交易 | 37 |
| EASYWALLETON | 悠遊付線上 | 38 |
| EASYWALLETOFF | 悠遊付線下 | 39 |
| PXPAYON | 全支付線上 | 56 |
| PXPAYOFF | 全支付線下 | 46 |
| PLUSPAYON | 全盈支付線上 | 52 |
| PLUSPAYOFF | 全盈支付線下 | 53 |
付款方式說明(對應付款類型)
| 付款方式 | 說明 | 備註 |
|---|---|---|
| 1 | 信用卡 | CREDITCARD |
| 9 | 海外信用卡 | ABROAD |
| 10 | 支付寶線上 | ALIPAY |
| 13 | 微信支付線上 | |
| 15 | LINE Pay線上 | LINEPAYON |
| 16 | LINE Pay線下 | LINEPAYOFF |
| 19 | 微信支付線下 | WECHATOFF |
| 27 | Pi 拍錢包線上 | PION |
| 28 | Pi 拍錢包線下 | PIOFF |
| 31 | 街口支付線上 | JKOON |
| 32 | 街口支付線下 | JKOOFF |
| 37 | 現金交易 | CASH |
| 38 | 悠遊付線上 | EASYWALLETON |
| 39 | 悠遊付線下 | EASYWALLETOFF |
| 56 | 全支付線上 | PXPAYON |
| 46 | 全支付線下 | PXPAYOFF |
| 52 | 全盈支付線上 | PLUSPAYON |
| 53 | 全盈支付線下 | PLUSPAYOFF |
自行收款付款方式
| 自行收款付款方式 | 說明 | 備註 |
|---|---|---|
| REMITTENCE | 轉帳匯款 | |
| ZINGALAPAY | 銀角零卡 | |
| LINEPAY | LINE Pay | |
| JKO | 街口支付 | |
| PI | Pi 拍錢包 | |
| EASYWALLET | 悠遊付 | |
| PXPAY | 全支付 | |
| PLUSPAY | 全盈支付 | |
| ALIPAY_YUANTABANK | 支付寶元大 | |
| ALIPAY_MEGABANK | 支付寶兆豐 | |
| ALIPAY_TCB | 支付寶合庫 | |
| WECHAT_SKBANK | 微信支付新光 | |
| MOMO | Momo收款 | |
| SHOPEE | 蝦皮拍賣收款 | |
| ETMALL | 東森收款 | |
| PCSTORE | PChome商店街收款 | |
| PCHOME24H | PChome24H收款 | |
| RUTEN | 露天拍賣收款 | |
| SHOPLINE | Shop line收款 | |
| FOODPANDA | 熊貓收款 | |
| UBEREATS | Uber eats收款 | |
| CYBERBIZ | Cyberbiz收款 | |
| YAHOOBID | YAHOO拍賣收款 | |
| RAKUTEN | 樂天市場收款 | |
| CAROUSELL | 旋轉拍賣收款 | |
| FACEBOOKGROUPS | FB社團收款 | |
| PINKOI | Pinkoi收款 | |
| 91APP | 91APP收款 | |
| COD_MYPAY | MYPAY物流代收 | |
| COD_HCT | 新竹物流代收 | |
| COD_TCAT | 黑貓宅急便代收 | |
| COD_MYSHIP711 | 7-ELEVEN賣貨便代收 | |
| COD_FAMISTORE | 好賣+代收 | |
| COD_HISHIPBUYER | 萊賣貨代收 | |
| COD_KERRYTJ | 嘉里大榮代收 | |
| CSTORECODE_IBON | 超商代碼(IBON) | |
| CSTORECODE_FAMIPORT | 超商代碼(FamiPort) | |
| CSTORECODE_LIFEET | 超商代碼(Life-ET) | |
| CSTORECODE_OKGO | 超商代碼(OK GO) | |
| ETICKET_EASYCARD | 悠遊卡 | |
| ETICKET_IPASS | 一卡通 | |
| ETICKET_ICASH | iCash | |
| CRYPTO_BTC | 比特幣 | |
| CRYPTO_ETH | 乙太幣 | |
| TELECOM_CHT | 中華電信代收 | |
| TELECOM_FET | 遠傳電信代收 | |
| TELECOM_TWM | 台灣大哥大代收 | |
| TELECOM_TSTAR | 台灣之星代收 | |
| TELECOM_APT | 亞太電信代收 | |
| ECPAY_CREDIT | 綠界收款(信用卡) | |
| ECPAY_WEBATM | 綠界收款(網路ATM) | |
| ECPAY_ATM | 綠界收款(自動櫃員機) | |
| ECPAY_CVS | 綠界收款(超商代碼) | |
| ECPAY_BARCODE | 綠界收款(超商條碼) | |
| ECPAY_TWQR | 綠界收款(行動支付) | |
| ECPAY_IN_STORE_PICKUP | 綠界收款(超取) | |
| NEWEBPAY_CREDIT | 藍新收款(信用卡付款) | |
| NEWEBPAY_VACC | 藍新收款(銀行 ATM 轉帳付款) | |
| NEWEBPAY_WEBATM | 藍新收款(網路銀行轉帳付款) | |
| NEWEBPAY_BARCODE | 藍新收款(超商條碼繳費) | |
| NEWEBPAY_CVS | 藍新收款(超商代碼繳費) | |
| NEWEBPAY_LINEPAY | 藍新收款(LINE Pay 付款) | |
| NEWEBPAY_ESUNWALLET | 藍新收款(玉山 Wallet) | |
| NEWEBPAY_TAIWANPAY | 藍新收款(台灣 Pay) | |
| NEWEBPAY_CVSCOM | 藍新收款(超商取貨付款) | |
| CREDITCARD_TCB | 信用卡(合庫銀行) | |
| CREDITCARD_ESUNBANK | 信用卡(玉山銀行) | |
| CREDITCARD_FIRSTBANK | 信用卡(第一銀行) | |
| CREDITCARD_FUBONBANK | 信用卡(台北富邦銀行) | |
| CREDITCARD_TSIB | 信用卡(台新銀行) | |
| CREDITCARD_NCCC | 信用卡(聯信) | |
| CREDITCARD_CTBC | 信用卡(中信銀行) | |
| CREDITCARD_KGIBANK | 信用卡(凱基銀行) | |
| CREDITCARD_YUANTABANK | 信用卡(元大銀行) | |
| CREDITCARD_CUB | 信用卡(國泰世華銀行) | |
| CREDITCARD_BANKSINOPAC | 信用卡(永豐銀行) | |
| CREDITCARD_MEGABANK | 信用卡(兆豐銀行) | |
| CREDITCARD_GLOBALPAYMENTS | 信用卡(環匯亞太) | |
| AMEX_TSIB | 美國運通(台新銀行) | |
| AMEX_CTBC | 美國運通(中信銀行) | |
| AMEX_NCCC | 美國運通(聯信) | |
| UNIONPAY_TCB | 銀聯卡(合庫銀行) | |
| UNIONPAY_ESUNBANK | 銀聯卡(玉山銀行) | |
| UNIONPAY_NCCC | 銀聯卡(聯信) | |
| UNIONPAY_TSIB | 銀聯卡(台新銀行) | |
| UNIONPAY_KGIBANK | 銀聯卡(凱基銀行) | |
| UNIONPAY_YUANTABANK | 銀聯卡(元大銀行) | |
| UNIONPAY_BANKSINOPAC | 銀聯卡(永豐銀行) | |
| UNIONPAY_CUB | 銀聯卡(國泰世華銀行) | |
| BARCODE_SKBANK | 超商繳費條碼(新光銀行) | |
| BARCODE_ESUNBANK | 超商繳費條碼(玉山銀行) | |
| BARCODE_CTBC | 超商繳費條碼(中信銀行) | |
| TWPAY_BOT | 台灣Pay(台灣銀行) | |
| TWPAY_LANDBANK | 台灣Pay(台灣土地銀行) | |
| TWPAY_TCB | 台灣Pay(合庫銀行) | |
| TWPAY_FIRSTBANK | 台灣Pay(第一銀行) | |
| TWPAY_HNCB | 台灣Pay(華南銀行) | |
| TWPAY_CHB | 台灣Pay(彰化銀行) | |
| TWPAY_SCSB | 台灣Pay(上海商銀) | |
| TWPAY_CUB | 台灣Pay(國泰世華銀行) | |
| TWPAY_MEGABANK | 台灣Pay(兆豐銀行) | |
| TWPAY_BOK | 台灣Pay(高雄銀行) | |
| TWPAY_TBB | 台灣Pay(台灣企銀) | |
| TWPAY_KTB | 台灣Pay(京城銀行) | |
| TWPAY_HWATAIBANK | 台灣Pay(華泰銀行) | |
| TWPAY_SUNNYBANK | 台灣Pay(陽信銀行) | |
| TWPAY_KSCC | 台灣Pay(基隆二信) | |
| TWPAY_TFCCBANK | 台灣Pay(淡水一信) | |
| TWPAY_HCFCBANK | 台灣Pay(新竹一信) | |
| TWPAY_TSCA | 台灣Pay(台中二信) | |
| TWPAY_CH6C | 台灣Pay(彰化六信) | |
| TWPAY_HL2C | 台灣Pay(花蓮二信) | |
| TWPAY_ESUNBANK | 台灣Pay(玉山銀行) | |
| TWPAY_TSIB | 台灣Pay(台新銀行) | |
| TWPAY_AFISC | 台灣Pay(農金資) | |
| TWPAY_YUANTABANK | 台灣Pay(元大銀行) | |
| TWPAY_CTBC | 台灣Pay(中信銀行) | |
| TWPAY_FAST | 台灣Pay(南農中心) | |
| TWPAY_SCU | 台灣Pay(南資中心) | |
| DS_SHINSHIN | 欣欣大眾 | |
| DS_MINGYAO | 明曜百貨 | |
| DS_DAYEH | 大葉高島屋 | |
| DS_CHUNGYO | 中友百貨 | |
| DS_KSSOGO | 廣三SOGO百貨 | |
| DS_FOCUSQUARE | Focus時尚流行館 | |
| DS_NICEPLAZA | 耐斯廣場 | |
| DS_DREAMMALL | 夢時代購物中心 | |
| DS_UNIUSTYLE | 統一時代百貨 | |
| DS_PARKLANES | 金典綠園道商場 | |
| DS_CITYPLAZA | 大都會廣場 | |
| DS_LIHPAOMALL | 麗寶百貨廣場 | |
| DS_EDORAPARK | 瀚星百貨 | |
| DS_BEYONDPLAZA | 比漾廣場 | |
| DS_HAYASHI | 林百貨 | |
| DS_SHINESQUARE | 昕境廣場 | |
| DS_LANDMARKLIFEPLAZA | 置地生活廣場 | |
| DS_TONLIN | 統領廣場 | |
| DS_HONHUI | 宏匯廣場 | |
| DS_TSRD | 南紡購物中心 | |
| DS_FEDS_XINYIA13 | 遠東百貨-遠百信義 A13 | |
| DS_FEDS_BANQIAO | 遠東百貨-板橋中山店 | |
| DS_FEDS_TAOYUAN | 遠東百貨-桃園店 | |
| DS_FEDS_ZHUPEI | 遠東百貨-竹北店 | |
| DS_FEDS_CHIAYI | 遠東百貨-嘉義店 | |
| DS_FEDS_HUALIEN | 遠東百貨-花蓮店 | |
| DS_FEDS_MEGACITY_BANQIAO | 遠東百貨-MegaCity板橋大遠百 | |
| DS_FEDS_HSINCHU | 遠東百貨-新竹大遠百 | |
| DS_FEDS_TOPCITY_TAICHUNG | 遠東百貨-Top City台中大遠百 | |
| DS_FEDS_TAINAN_GONGYUAN | 遠東百貨-台南大遠百公園店 | |
| DS_FEDS_TAINAN_CHENGKUNG | 遠東百貨-台南大遠百成功店 | |
| DS_FEDS_KAOHSIUNG | 遠東百貨-高雄大遠百 | |
| DS_SKM_XINYI | 新光三越-台北信義新天地 | |
| DS_SKM_TAIPEI_STATION | 新光三越-台北站前店 | |
| DS_SKM_TAIPEI_NANJING_W | 新光三越-台北南西店 | |
| DS_SKM_TAIPEI_TIANMU | 新光三越-台北天母店 | |
| DS_SKM_TAOYUAN_STATION | 新光三越-桃園站前店 | |
| DS_SKM_TCAIHUNG_PORT | 新光三越-台中中港店 | |
| DS_SKM_CHIAYI_CHUIYANG | 新光三越-嘉義垂楊店 | |
| DS_SKM_TAINAN_ZHONGSHAN | 新光三越-台南中山店 | |
| DS_SKM_TAINAN_XIMEN | 新光三越-台南西門店 | |
| DS_SKM_KAOHSIUNG_SANDUO | 新光三越-高雄三多店 | |
| DS_SKM_KAOHSIUNG_ZUOYING | 新光三越-高雄左營店 | |
| DS_SKM_PARK | 新光三越-SKM Park Outlets 高雄草衙 | |
| DS_SOGO_TAIPEI_ZHONGXIAO | 遠東SOGO百貨-台北忠孝館 | |
| DS_SOGO_TAIPEI_FUXING | 遠東SOGO百貨-台北復興館 | |
| DS_SOGO_TAIPEI_DUNHUA | 遠東SOGO百貨-台北敦化館 | |
| DS_SOGO_TIANMU | 遠東SOGO百貨-天母店 | |
| DS_SOGO_ZHONGLI | 遠東SOGO百貨-中壢店 | |
| DS_SOGO_HSINCHU | 遠東SOGO百貨-新竹店 | |
| DS_SOGO_KAOHSIUNG | 遠東SOGO百貨-高雄店 | |
| DS_PACIFIC_FENGYUAN | 太平洋百貨-豐原 | |
| DS_PACIFIC_PINGTUNG | 太平洋百貨-屏東 | |
| DS_PACIFIC_SUNNYPARK | 太平洋百貨-Sunny Park日光廣場 | |
| DS_PACIFIC_PINGTUNG_GONGYONG | 太平洋百貨-屏東驛站商場 | |
| DS_PACIFIC_PINGTUNG_GUANGFU | 太平洋百貨-屏東轉運站商場 | |
| DS_PACIFIC_CHAOZHOU | 太平洋百貨-潮州驛站商場 | |
| DS_HANSHIN_KAOHSIUNG | 漢神百貨 | |
| DS_HANSHIN_ARENA | 漢神巨蛋購物廣場 | |
| DS_BREEZE_CENTER | 微風廣場 | |
| DS_BREEZE_TAIPEISTATION | 微風台北車站 | |
| DS_BREEZE_NTUHOSPITAL | 微風台大醫院商場 | |
| DS_BREEZE_NANJING | 微風南京 | |
| DS_BREEZE_XINYI | 微風信義 | |
| DS_BREEZE_SONGGAO | 微風松高 | |
| DS_BREEZE_NANSHAN | 微風南山 | |
| DS_BREEZE_TSGHOSPITAL | 微風三總商店街 | |
| DS_BREEZE_ACADEMIASINICA | 微風中央研究院 | |
| DS_GM_ZHONGHE | GlobalMall-新北中和 | |
| DS_GM_BANQIAO | GlobalMall-環球板橋車站 | |
| DS_GM_A8 | GlobalMall-環球桃園A8 | |
| DS_GM_A19 | GlobalMall-環球桃園A19 | |
| DS_GM_A9 | GlobalMall-環球林口A9 | |
| DS_GM_NANGANG | GlobalMall-環球南港車站 | |
| DS_GM_XINZUOYING | GlobalMall-環球新左營車站 | |
| DS_GM_PINGTUNG | GlobalMall-環球屏東市 | |
| DS_TRK_MALL | 大魯閣新時代購物中心 | |
| DS_TRK_SQUARE | 大魯閣湳雅廣場 | |
| DS_TALEE_WUFU | 大立大統五福店 | |
| DS_TALEE_A | 大立百貨A館 | |
| DS_TALEE_B | 大立百貨B館 | |
| DS_MITSUI_OUTLET_TAICHUNGPORT | MITSUI OUTLET PARK 台中港 | |
| DS_MITSUI_OUTLET_TAINAN | MITSUI OUTLET PARK 台南 | |
| DS_MITSUI_OUTLET_LINKOU | MITSUI OUTLET PARK 林口 | |
| DS_MITSUI_LALAPORT_TAICHUNG | Mitsui Shopping Park LaLaport 台中 |
MYPAY APP測試流程
直接交易
- 從應用市場中安裝最新版本的MYPAY APP。
- 進入MYPAY APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。
- 離開MYPAY APP,並在串接方App中將資料傳入MYPAY APP進行動作。
TAP交易(只有MYPAY TAP APP支援)
- 從應用市場中安裝最新版本的MYPAY TAP APP。
- 進入MYPAY TAP APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。
- 離開MYPAY TAP APP,並在串接方App中將資料傳入MYPAY TAP APP進行動作。
一卡通交易(Lib 0.2.0)
- 從應用市場中安裝最新版本的MYPAY APP。
- 進入MYPAY APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。
- 離開MYPAY APP,並在串接方App中將資料傳入MYPAY APP進行動作。
其它動作(Lib 0.1.5)
- 從應用市場中安裝最新版本的MYPAY APP。
- 進入MYPAY APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。
- 離開MYPAY APP,並在串接方App中將資料傳入MYPAY APP進行動作。
MYPAY頁面(Lib 0.1.8)
- 從應用市場中安裝最新版本的MYPAY APP。
- 進入MYPAY APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。
- 離開MYPAY APP,並在串接方App中將資料傳入MYPAY APP進入指定的頁面。
39Buy交易(Lib 0.0.56)
從應用市場中安裝最新版本的MYPAY APP。
進入MYPAY APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。
離開MYPAY APP,在串接方App中將資料傳入MYPAY APP進行手動登入,取得token。
每次對MYPAY APP進行動作時須將appToken傳入。
若MYPAY APP返回token無效的錯誤,請再重新手動登入以取得新的token,再進行其它動作。
藍牙串接 (APP v3.9.0)
從應用市場中安裝最新版本的MYPAY APP。
進入MYPAY APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。
串接方使用的裝置和已安裝MYPAY APP的設備配對藍牙。
將藍牙傳輸設定頁面中確認的藍牙串接ID加入串接方程式。
離開MYPAY APP (Android 11以上的設備,請開啟MYPAY APP,若關閉APP,可能會有收到不請求的問題),在串接方程式中將資料加密並透過藍牙傳入MYPAY APP進行動作。
瀏覽器串接 (APP v3.9.1)
從應用市場中安裝最新版本的MYPAY APP。
進入MYPAY APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。
離開MYPAY APP,並在串接方Web程式中將資料加密並透過Intent傳入MYPAY APP進行動作。
版本紀錄
MyPayCommon
| 版本號 | 日期 | 異動 |
|---|---|---|
| 0.0.34 | 2021-06-07 | 新增︰ 1. PrintRequest & PrintResponse (可列印發票加明細、單純發票、單純明細) 2. Item.isPrintOut (是否可以在明細上印出) 棄用︰ PrintInvoiceRequest & PrintInvoiceResponse (列印發票) |
| 0.0.45 | 2021-08-09 | 新增︰ 1. ActionDetails串接方式 2. 所有可使用的AppRequest常數至Constant中 3. 列印的AppRequest.logoBase64 |
| 0.0.50 | 2021-09-01 | 新增︰ Constant.PRINT_MODE_CREDIT_CARD_RECEIPT (可重印簽單) |
| 0.0.51 | 2021-09-02 | 新增︰ Constant.CREDIT_CARD_RECEIPT_TYPE_ALL & Constant.CREDIT_CARD_RECEIPT_TYPE_ONLY_CUSTOMER_RECEIPT (可列印商店存根加持卡人存根、單純持卡人存根) |
| 0.0.56 | 2021-12-30 | 新增︰ Constant.ACTION_39_BUY_ADD_LIGHT_PRODUCT Constant.ACTION_39_BUY_ADD_PRODUCT_LEVEL Constant.ACTION_39_BUY_EDIT_LIGHT_PRODUCT Constant.ACTION_39_BUY_EDIT_PRODUCT_LEVEL Constant.ACTION_39_BUY_LOGIN Constant.ACTION_39_BUY_LOGOUT Constant.ACTION_39_BUY_QUERY_ORDER Constant.ACTION_39_BUY_QUERY_ORDER_DETAILS Constant.ACTION_39_BUY_QUERY_PRODUCT Constant.ACTION_39_BUY_QUERY_PRODUCT_DETAILS Constant.ACTION_39_BUY_QUERY_PRODUCT_LEVEL Constant.ACTION_39_BUY_QUERY_PRODUCT_LEVEL_DETAILS Constant.ACTION_39_BUY_QUERY_PRODUCT_LEVEL_RELATION Constant.ACTION_39_BUY_SEND_LIGHT_TRANSACTION Constant.ACTION_39_BUY_UPDATE_PRODUCT_LEVEL_RELATION Constant.ACTION_39_BUY_VALIDATE_APP_TOKEN 棄用︰ 舊版API |
| 0.0.57 | 2022-02-16 | 新增︰ Constant.ACTION_39_BUY_ADD_DONATION_PRODUCT Constant.ACTION_39_BUY_ADD_GENERAL_PRODUCT Constant.ACTION_39_BUY_ADD_QUICK_PAY_PRODUCT Constant.ACTION_39_BUY_ADD_RELEASE_PRODUCT Constant.ACTION_39_BUY_EDIT_DONATION_PRODUCT Constant.ACTION_39_BUY_EDIT_GENERAL_PRODUCT Constant.ACTION_39_BUY_EDIT_QUICK_PAY_PRODUCT Constant.ACTION_39_BUY_EDIT_RELEASE_PRODUCT Constant.ACTION_39_BUY_SEND_DONATION_TRANSACTION Constant.ACTION_39_BUY_SEND_GENERAL_TRANSACTION Constant.ACTION_39_BUY_SEND_QUICK_PAY_TRANSACTION Constant.ACTION_39_BUY_SEND_RELEASE_TRANSACTION |
| 0.1.0 | 2022-03-07 | 刪除︰ 所有舊版API (不向下相容) |
| 0.1.1 | 2022-05-03 | 新增︰ Constant.BUY_39_PRINT_MODE_FREE_OF_INVOICE_RECEIPT Constant.BUY_39_PRINT_MODE_FARMER_FISHERMAN_RECEIPT |
| 0.1.2 | 2022-05-19 | 新增︰ Constant.ACTION_FASSTAP |
| 0.1.3 | 2022-06-13 | 新增︰ Constant.ACTION_TAP 刪除︰ Constant.ACTION_FASSTAP (不向下相容) |
| 0.1.5 | 2022-06-30 | 新增︰ Constant.ACTION_SCAN_CODE |
| 0.1.6 | 2022-07-05 | 新增︰ Constant.ACTION_39_BUY_SEND_SCAN_ITEM_TRANSACTION |
| 0.1.7 | 2022-07-29 | 新增︰ Constant.ACTION_39_BUY_REFUND_SCAN_ITEM |
| 0.1.8 | 2022-08-08 | 新增︰ Constant.PAGE_MYPAY_ORDER_LIST |
| 0.1.9 | 2022-09-05 | 新增︰ Constant.PAGE_MYPAY_FOOD_ORDER_LIST Constant.PAGE_MYPAY_INVOICE_MANAGEMENT Constant.PAGE_MYPAY_RECEIPT_MANAGEMENT Constant.PAGE_MYPAY_PRINTER_SETTINGS Constant.PAGE_MYPAY_URL_SETTINGS |
| 0.2.0 | 2022-10-04 | 新增︰ Constant.ACTION_I_PASS_CANCEL Constant.ACTION_I_PASS_CLOSE_BATCH Constant.ACTION_I_PASS_QUERY_CARD Constant.ACTION_I_PASS_REDEEM Constant.ACTION_I_PASS_REFUND Constant.ACTION_I_PASS_RELOAD Constant.PAGE_MYPAY_SETTLEMENT_SETTINGS |
| 0.2.2 | 2022-10-07 | 新增︰ Constant.ACTION_I_PASS_SEND_TRANSACTION Constant.RECEIPT_TYPE_FREE_OF_INVOICE_RECEIPT Constant.RECEIPT_TYPE_FARMER_FISHERMAN_RECEIPT 刪除︰ Constant.ACTION_I_PASS_CANCEL (不向下相容) Constant.ACTION_I_PASS_REDEEM (不向下相容) Constant.ACTION_I_PASS_REFUND (不向下相容) Constant.ACTION_I_PASS_RELOAD (不向下相容) |
| 0.2.3 | 2022-10-12 | 新增︰ Constant.PRINT_MODE_FREE_OF_INVOICE_RECEIPT Constant.PRINT_MODE_FARMER_FISHERMAN_RECEIPT |
| 0.2.4 | 2022-11-22 | 新增︰ Constant.ACTION_QUERY_COUPON_CODE |
| 0.2.5 | 2022-12-19 | 新增︰ Constant.ACTION_GET_SUPPORTED_PAY_MODES |
| 0.2.6 | 2023-01-31 | 新增︰ Constant.PAY_MODE_ID_EASY_WALLET Constant.BUY_39_PAY_MODE_ID_EASY_WALLET |
| 0.2.7 | 2023-03-21 | 新增︰ Constant.PAGE_MYPAY_SETTLEMENT_REPORT |
| 0.2.8 | 2023-09-13 | 刪除︰ Constant.PAGE_MYPAY_SETTLEMENT_SETTINGS (不向下相容) |
| 0.2.9 | 2024-01-09 | 新增︰ Constant.PAY_MODE_ID_PLUS_PAY Constant.PAY_MODE_ID_PX_PAY |
| 0.3.0 | 2024-01-18 | 新增︰ Constant.ACTION_GET_SUPPORTED_ACTUAL_PAY_MODES |
| 0.3.1 | 2024-02-07 | 新增︰ Constant.ACTION_SCAN_CODE_FLUTTER_LIB (實驗性功能) |
| 0.3.2 | 2024-06-24 | 新增︰ Constant.PAGE_MYPAY_ORDER_DETAILS 刪除︰ Constant.ACTION_SCAN_CODE_FLUTTER_LIB (不向下相容) |
| 0.3.3 | 2024-07-08 | 新增︰ Constant.ACTION_TAP_REFUND |
| 0.3.4 | 2024-10-14 | 新增︰ Constant.ACTION_CREATE_INVOICE 修正︰ Constant.CLOUD_TYPE_MOBILE_BARCODE (1 -> 2) Constant.CLOUD_TYPE_NATURAL_PERSON_BARCODE (2 -> 3) Constant.CLOUD_TYPE_EMAIL (3 -> 4) |
| 0.3.5 | 2024-11-21 | 新增︰ Constant.PAGE_MYPAY_DEVICE_SETTINGS Constant.PAGE_MYPAY_MEMBER_API_SETTINGS Constant.PAGE_MYPAY_MEMBER_CARD_POINTS Constant.PAGE_MYPAY_REDEEM_VOUCHER |
| 0.3.6 | 2025-08-20 | 新增︰ Constant.ACTION_TAP_INIT |
注意︰
- 0.0.56之後只支援ActionDetails串接方式,不接受舊版API的串接方式呼叫MYPAY APP。
- 0.1.8之後新增以PAGE_開頭的動作,相關動作可讓串接方App直接使用MYPAY APP定義的頁面,無需自行開發。
- 標記"不向下相容"之項目,串接方App若有影響必須對其程式進行修正,以避免上線時發生不可預期的問題。
- 標記"實驗性功能"之項目,為實驗測試功能,主要只會更新在測試版本上,請避免在正式版本中串接此功能。
MYPAY APP
| 版本號 | 測試更新日期 | 正式更新日期 | 異動 | 對應Lib版本 |
|---|---|---|---|---|
| 2.2.0 | 2021-06-16 | 修正︰ 1. 所有交易列印單據與發票流程 2. 部分流程與問題 | 0.0.34 | |
| 2.2.1 | 2021-06-18 | 2021-06-22 | 修正︰ 部分文字 刪除︰ 交易列印收據流程 | 0.0.34 |
| 2.4.2 | 2021-08-23 | 新增︰ 1. Cross App使用ActionDetails方式串接 2. API呼叫卡機重印或補印發票 3. 列印標題圖片可使用logoBase64 修正︰ 1. 推播部分流程與錯誤 2. 部分卡片無法感應問題 3. 完善訂單列印流程 | 0.0.45 | |
| 2.4.3 | 新增︰ 1. 交易金額3000元以下簽單免簽 2. Cross App可使用重印簽單功能 修正︰ 1. 信用卡簽單格式 2. Cross App列印發票無圖片資料時,標題圖片為空白問題 | 0.0.50 | ||
| 2.4.4 | 新增︰ Cross App可使用列印商店存根加持卡人存根、單純持卡人存根(AppRequest.creditCardReceiptType) | 0.0.51 | ||
| 2.4.5 | 2021-09-15 | 新增︰ 1. API可使用重印簽單功能 2. API可使用列印商店存根加持卡人存根、單純持卡人存根 3. API可使用列印點餐單明細功能 4. API可使用退款功能 修正︰ 信用卡交易無發票時閃退問題 | 0.0.51 | |
| 2.4.6 | 2021-09-27 | 新增︰ 1. API可使用列印點餐單功能 2. 訂單通知音效 | 0.0.51 | |
| 2.4.7 | 2021-09-28 | 修正︰ 推播錯誤無顯示訊息問題 | 0.0.51 | |
| 2.4.8 | 2021-09-29 | 2021-09-29 | 修正︰ 1. 多個訂單列印無反應問題 2. 信用卡簽單格式 | 0.0.51 |
| 2.4.9 | 2021-10-14 | 新增︰ 點餐單管理功能 修正︰ 1. 點餐單列印順序問題 3. 新訂單音效播放問題 4. 列印訂單發票時間問題 5. 訂單發票多通知問題 | 0.0.51 | |
| 2.5.0 | 2021-11-12 | 新增︰ 訂單管理功能 修正︰ 1. 讀卡Undefined錯誤顯示問題 2. 帳號無金鑰錯誤顯示與流程問題 | 0.0.51 | |
| 2.5.1 | 2021-11-16 | 修正︰ 1. 讀卡金額有小數時-50019問題 2. 訂單管理顯示當日交易問題 | 0.0.51 | |
| 2.5.2 | 2021-11-18 | 修正︰ 1. Cross App舊版退款問題 2. Cross App ActionDetails查詢交易未回傳key問題 | 0.0.51 | |
| 2.5.3 | 2021-11-23 | 新增︰ DB Migration機制 修正︰ Cross App ActionDetails查詢交易未回傳cardNo問題 | 0.0.51 | |
| 2.5.4 | 2021-11-24 | 2021-11-30 | 修正︰ 1. 信用卡交易問題 2. Cross App ActionDetails查詢交易未回傳refundUidList問題 | 0.0.51 |
| 2.5.5 | 2021-12-01 | 2021-12-01 | 快速修正︰ 1. 無法進入登入頁問題 2. 任務列表為Service | 0.0.51 |
| 2.5.6 | 2021-12-07 | 新增︰ 一卡通測試頁面 修正︰ 有統編發票格式問題 | 0.0.51 | |
| 2.5.7 | 2022-01-06 | 新增︰ 1. 阻擋Cross App舊版API呼叫方式 2. Cross App支援39Buy登入、登出、驗證Token、產品、訂單功能 修正︰ 隱藏一卡通測試頁面 | 0.0.56 | |
| 2.5.8 | 2022-01-24 | 2022-02-14 | 新增︰ Cross App支援39Buy點燈交易功能 | 0.0.56 |
| 2.5.9 | 2022-02-11 | 修正︰ 一卡通測試交易結果顯示 | 0.0.56 | |
| 2.6.0 | 2022-02-21 | 新增︰ 1. Cross App支援39Buy新增修改一般、捐款、一碼付與超渡產品功能 2. Cross App支援39Buy一般、捐款、一碼付與超渡交易功能 修正︰ 部分39Buy API缺少欄位與錯誤 | 0.0.57 | |
| 3.0.0 | 2022-03-21 | 新增︰ 1. 刪除超過半年的Local交易紀錄 2. 交易狀態Local紀錄 3. 交易成功失敗回傳後端 4. 讀卡流程可手動取消 修正︰ 1. SoundUtils NPE問題 2. Cross App交易回傳流程問題 3. 讀卡無執行完整EMV流程問題 刪除︰ 所有Cross App舊版API程式 (不向下相容) | 0.1.0 | |
| 3.1.0 | 2022-04-22 | 新增︰ 1. 支援不同的Driver程式 2. 發票管理頁面 修正︰ 1. Cross App判斷錯誤storeUid問題 (不向下相容) 2. Cross App MyPay使用現金未阻擋問題 3. Cross App 39Buy auth必須傳入storeUid問題 4. DB Migration未執行問題 5. 有統編發票無列印item列表問題 更新︰ 顯示Toast與Dialog UI | 0.1.0 | |
| 3.1.1 | 2022-04-22 | 2022-04-29 | 修正︰ 發票與明細格式 | 0.1.0 |
| 3.1.3 | 2022-05-17 | 2022-05-19 | 新增︰ 1. 判斷AppRequest必要值 (不向下相容) 2. 39Buy交易狀態Local紀錄 3. Cross App 39Buy可列印免用統一發票收據與農漁民收據 4. 訂單列表與明細顯示交易類型 修正︰ 1. 信用卡NFC感應限額問題 2. JCB感應NFC錯誤問題 3. 重印簽單問題 4. 取得發票號碼閃退問題 5. 列印失敗NPE問題 | 0.1.1 |
| 3.1.5 | 2022-06-15 | 新增︰ 1. 處理交易中斷機制 2. 判斷Cross App MyPay退款時不可帶入空的uid與key (不向下相容) 3. 訂單列表可查詢LOG狀態 修正︰ 1. 部分交易9999錯誤為可預期的錯誤 2. 退款回傳錯誤的uid問題 3. Local交易狀態紀綠在交易錯誤時訂單日期為空的問題 4. Local交易狀態可區分交易成功,列印失敗的情況 5. 重複退款時產生多筆Local交易狀態紀綠問題 6. Cross App MyPay查詢交易未回傳status與statusMsg問題 | 0.1.2 | |
| 3.1.6 | 2022-06-22 | 2022-06-23 | 新增︰ 1. 印表機設定頁面 2. 支援商米雲端印表機列印功能 修正︰ 1. Cross App 39Buy LINEPay線上查詢交易結果直接返回問題 2. Cross App 39Buy使用Customer、Invoice、Echo參數傳入 (不向下相容) 3. Cross App 39Buy交易Item欄位支援列印單據品項 4. 進入APP無網路時畫面卡住問題 5. MYPAY TAP流程與UI問題 6. API呼叫卡機紀錄Local交易流程問題 | 0.1.3 |
| 3.1.7 | 2022-08-04 | 新增︰ 1. Cross App掃碼回傳功能 2. Cross App 39Buy任意付交易與任意付退款功能 3. 商米雲端印表機可列印免用統一發票收據與農漁民收據 4. 印表機設定頁面可選擇印表機優先權與測試列表功能 5. 免用統一發票收據與農漁民收據列印可使用local圖片 修正︰ 1. Android O以上使用JobService 2. 發票QR Code容錯率為L且右邊QR Code最多只保留兩個商品資訊 3. 處理交易中斷機制發動時機 4. 掃碼收款使用自訂的照機頁面 5. Cross App 39Buy登入未儲存profile問題 6. Cross App 39Buy交易使用免用統一發票收據與農漁民收據傳入Item格式 7. Cross App 39Buy取得訂單列表總金額格式與未回傳orderId問題 8. 39Buy雲端訂單列印流程 9. 單據管理頁面問題 10. 商米雲端印表機列印發票與簽單格式問題 刪除︰ 定時處理交易中斷機制 | 0.1.7 | |
| 3.2.0 | 2022-08-12 | 新增︰ Cross App金流訂單列表功能 修正︰ Cross App金流交易不支援現金交易問題 | 0.1.8 | |
| 3.2.1 | 2022-08-23 | 新增︰ 1. 交易回傳設定頁面 2. 回傳金流交易與退款結果流程 修正︰ Cross App金流訂單明細頁UI與顯示的資料 更新︰ Cross App金流訂單列表頁之搜尋工具條件為支付工具、金流編號、訂單編號、發票號碼等多條件 | 0.1.8 | |
| 3.2.2 | 2022-08-31 | 修正︰ 1. Cross App金流訂單列表頁以發票號碼查詢無顯示退款交易問題 2. Cross App金流訂單明細頁重印退款簽單與補印發票問題 3. 交易或退款成功response的aCode為null與未隱藏列印資訊問題 | 0.1.8 | |
| 3.2.3 | 2022-09-06 | 新增︰ Device ID資訊頁面 修正︰ 1. 非卡機之一般裝置停在App進入頁問題 2. 印表機設定頁測試列印問題 3. 發票列印左右QR Code大小問題 | 0.1.8 | |
| 3.2.4 | 2022-09-07 | 修正︰ 1. QR Code線上交易頁QR Code位置 2. QR Code線上交易無發票時回應280問題 3. 發票列印左右QR Code大小問題 | 0.1.8 | |
| 3.2.5 | 2022-09-12 | 2022-09-13 | 新增︰ 1. Cross App點餐單列表功能 2. Cross App發票管理功能 3. Cross App收據管理功能 4. Cross App印表機設定功能 5. Cross App交易回傳設定功能 6. 交易回傳結果多回傳一碼付echo 修正︰ 部分頁面隱藏鍵盤問題 | 0.1.9 |
| 3.3.0 | 2022-10-05 | 新增︰ 1. Cross App一卡通交易功能 2. Cross App結班設定功能 3. 處理錯誤device id機制 修正︰ 1. 交易回傳結果一碼付echo名稱問題 2. 訂單明細頁右方資料顯示問題 | 0.2.0 | |
| 3.3.1 | 修正︰ 1. Cross App金流交易無法列印免用統一發票收據與農漁民收據問題 2. Cross App一卡通交易使用單一action 3. Cross App一卡通快速與離線詢卡未顯示錯誤訊息問題 4. Cross App一卡通連線詢卡未判斷order id問題 (不向下相容) | 0.2.3 | ||
| 3.3.2 | 2022-11-01 | 新增︰ 1. 阻擋螢幕截圖功能 2. Device資訊頁可確認設備型號 修正︰ 1. K2 MINI上掃描使用相機問題 2. 登入頁在部分設備上無法捲動問題 | 0.2.3 | |
| 3.3.6 | 2022-12-14 | 新增︰ 1. 加密App敏感性資料 2. DB Migration進度更新頁面與流程 3. 驗證使用者輸入資料,並於輸入資料正確後才可點擊按鈕進行後續動作 4. 登入頁可選紀錄登入資訊 5. 特店金鑰過期提示 6. 支援一碼付合作夥伴API流程 修正︰ 1. 未先登入MYPAY APP無顯示錯誤訊息問題 2. 發票字軌設定相關頁面無法捲動問題 3. 下拉式選單項目太小點擊異常問題 4. 登入頁輸入商務代號與登入帳號為可隱碼 5. 交易查詢改為先查詢Local DB資料而後才為Server端的資料 更新︰ 1. 保留Local DB交易區間(半年 -> 1個月) 2. 取得發票數量位數(4 -> 3) | 0.2.4 | |
| 3.3.7 | 2022-12-27 | 2023-01-05 | 新增︰ 1. Cross App取得特店支援的支付方式功能 2. 處理國外信用卡交易流程與警示 修正︰ 1. Cross App參數錯誤相對應的錯誤訊息 2. 判斷發票可列印的條件 3. 部分交易無法列印免用統一發票收據與農漁民收據問題 4. QR Code線上交易使用雲端發票參數卻會印出發票問題 更新︰ 頁面名稱 (交易回傳設定 -> 合作夥伴URL設定) | 0.2.5 |
| 3.3.8 | 2023-01-10 | 修正︰ 1. QR Code線上交易列印發票錯誤問題 2. Local DB紀綠deviceId、一碼付echo、itemList為空值問題 3. 金流訂單列表頁以發票號碼查詢無包含時間條件問題 4. 金流訂單列表頁以發票號碼查詢無資料問題 5. 金流訂單明細頁參數錯誤時還可進行退款問題 6. 一碼付合作夥伴交易回傳條件 | 0.2.5 | |
| 3.3.10 | 2023-01-16 | 2023-01-16 | 修正︰ 1. Cross App金流退款未傳入invoiceState參數問題 2. Local DB無交易時無法退款問題 3. 無法重印國外信用卡簽單問題 | 0.2.5 |
| 3.3.11 | 2023-02-01 | 新增︰ Cross App金流QR Code線上交易支援悠遊付 修正︰ 1. Cross App訂單查詢資料未完整問題 2. 收據管理頁無法拍照問題 | 0.2.6 | |
| 3.4.0 | 2023-02-16 | 新增︰ 金流訂單明細頁可更新交易狀態按鈕 修正︰ 1. 金流訂單明細頁訂單管理功能可使用條件 2. 印表機設定頁與API設定頁儲存和清除資料問題 更新︰ 1. MYPAY logo背景圖片 2. 新增發票區間頁與取得發票號碼頁UI | 0.2.6 | |
| 3.4.1 | 2023-03-06 | 2023-03-03 部分部署 | 新增︰ 金流訂單明細頁顯示發票類型 修正︰ 1. Device資訊頁Android 10以上設備閃退問題 2. 金流交易與訂單明細頁可列印發票條件 3. 金流退款時發票選項為作廢 | 0.2.6 |
| 3.4.2 | 2023-03-13 | 2023-03-10 部分部署 | 修正︰ 1. Cross App 39Buy登入頁鍵盤問題 2. Cross App取得特店支援的支付方式問題 | 0.2.6 |
| 3.5.0 | 2023-03-22 | 新增︰ Cross App結帳報表功能 | 0.2.7 | |
| 3.6.0 | 2023-04-07 | 修正︰ 結帳報表區間可重疊與可選未來時間問題 | 0.2.7 | |
| 3.6.1 | 2023-04-14 | 新增︰ 金流交易可列印交易明細功能(20230414) | 0.2.7 | |
| 3.6.4 | 2023-04-24 | 新增︰ 金流訂單明細頁可傳送交易結果功能 修正︰ 1. device id和model取得流程 2. 金流訂單明細頁按鈕可連續點擊問題 3. 金流訂單列表與明細頁退款錯誤與顯示問題 | 0.2.7 | |
| 3.6.5 | 2023-05-02 | 新增︰ 1. 金流訂單明細頁可重印交易明細功能 2. 金流訂單明細頁退款可選作廢折讓功能 修正︰ 1. 金流訂單明細頁退款交易未顯示發票資訊問題 2. 結帳報表資料未依特店顯示問題 3. 結帳報表錯誤訊息 4. 列印商品明細格式 5. 一卡通相關流程與顯示問題 | 0.2.7 | |
| 3.7.0 | 2023-05-25 | 新增︰ 1. 登入時儲存Gateway資訊 2. TAP交易回傳金流流程 3. 限制退款可選作廢折讓條件 4. 金流訂單列表頁顯示退款失敗訊息 修正︰ 結帳報表顯示錯誤流程與訊息 更新︰ 39Buy登入時儲存資料流程 | 0.2.7 | |
| 3.8.0 | 2023-07-26 | 新增︰ 1. 一卡通回傳金流交易流程 2. 結帳報表頁結帳時處理一卡通結班流程 修正︰ 1. 金流訂單列表頁顯示一卡通退款失敗訊息 2. 一卡通交易儲存Local DB的資料格式 更新︰ 39Buy登入頁登入權限 | 0.2.7 | |
| 3.8.2 | 2023-08-08 | 修正︰ 結帳報表頁閃退問題 | 0.2.7 | |
| 3.8.3 | 2023-08-09 | 2023-08-10 | 修正︰ 1. 商米V2無法取得SN問題 2. 部分工具release閃退問題 更新︰ 商米Printer取得驅動的程式 | 0.2.7 |
| 3.8.5 | 2023-08-24 | 2023-08-24 | 快速修正︰ 1. 金流訂單明細頁發票資訊在Server發生錯誤無回傳時無法重印問題 2. 發票左右QR Code大小不同問題 3. 商米讀卡大於0狀態碼問題 4. 無法在金流訂單列表頁查詢超過一個月以上的交易問題 | 0.2.7 |
| 3.9.0 | 2023-09-01 | 新增︰ 藍牙串接MYPAY APP功能(20230901_1、20230901_2) | 0.2.7 | |
| 3.9.1 | 2023-09-06 | 新增︰ Web串接MYPAY APP功能(20230906_1、20230906_2) | 0.2.7 | |
| 3.9.3 | 2023-10-13 | 2023-10-26 | 新增︰ Cross App 39Buy登入回傳device id (20230927_1) 修正︰ 1. 無法取得Provider問題 2. Cross App取得特店支援的支付方式為設備支援的支付方式(20230927_2) 3. TAP回傳與同步金流交易流程 4. TAP訂單明細頁訂單管理功能可使用條件 5. 一卡通同步金流相關問題 6. Cross App重印簽單多印一張問題 7. 藍牙設定頁Android 12以上設備閃退問題 | 0.2.8 |
| 4.0.0 | 2023-12-08 | 新增︰ 1. 發票字軌設定頁可切換發票開立模式 2. 發票區間列表頁 3. 離線發票開立功能 4. Cross App金流交易使用發票時驗證統一編號、手機載具、自然人憑證 5. 設備取得發票號碼只能是當月或下個月的限制 修正︰ 列印發票QR Code大小與商品資料過多問題 | 0.2.8 | |
| 4.0.2 | 2024-01-15 | 新增︰ 1. Cross App支援全盈支付線上和全支付線上 2. 一碼付切換使用者處理流程 修正︰ Cross Page使用錯誤的storeUid或userId未顯示錯誤訊息問題 | 0.2.9 | |
| 4.0.3 | 2024-01-17 | 修正︰ 1. userId驗證條件 2. 網路呼叫刷卡機重印簽單閃退問題 | 0.2.9 | |
| 4.0.5 | 2024-02-07 | 新增︰ 1. 自行收款設定頁面 2. Cross App取得自行收款設定 3. 發票開立模式設定頁 4. Flutter掃碼頁 修正︰ 先登入MYPAY APP再登入一碼付流程問題 更新︰ 發票字軌設定頁UI | 0.3.0 | |
| 4.0.7 | 2024-03-01 | 2024-03-04 | 新增︰ 藍牙掃碼功能 修正︰ 1. PayMode是否為信用卡的判斷 2. 海外信用卡交易列印問題 3. 金流訂單明細頁可更新交易狀態按鈕條件 4. 金流訂單明細頁第二次重印簽單只會印出商店存根問題 5. 金流訂單列表頁與MYPAY訂單列表頁搜尋交易結果無資料時列表不會更新問題 更新︰ 1. 頁面名稱 (藍牙設定 -> 藍牙傳輸設定) 2. 掃碼功能使用ML Lib 刪除︰ Flutter掃碼頁 | 0.3.0 |
| 4.0.9 | 2024-03-21 | 2024-03-25 | 新增︰ 1. 信用卡閘道設定錯誤提示訊息 2. 讀卡錯誤提示訊息 修正︰ 1. 一碼付重登入未更新特店金鑰問題 2. 列印自行收款明細問題 3. 交易無法列印免用統一發票收據與農漁民收據問題 4. 金流訂單列表頁查詢一個月以上交易無反應問題 5. 信用卡交易使用手機載具會列印出發票問題 6. 行動支付頁左上返回鍵點下無反應問題 7. 掃碼收款取消掃碼時會出現無法顯示Dialog錯誤問題 8. 照機頁按下拍照後閃退問題 更新︰ 顯示特店金鑰為前4後4碼 | 0.3.0 |
| 4.2.4 | 2024-05-08 | 2024-05-09 | 新增︰ 1. 12CM會員相關功能 2. Device資訊頁可確認Provider與EMV模組、印表機、掃描器是否可用資訊 3. 商米Printer錯誤時顯示錯誤碼與錯誤訊息 4. 中信加殼設定 5. 中信取消或退款失敗時重新執行另一動作流程 6. 回報結帳交易流程 修正︰ 1. 呼叫API前判斷金鑰過期流程 2. 藍牙串接無法退款問題 3. Tap交易使用中信T2P 4. 判斷商米EMV模組是否可用條件 5. AndroidManifest支援的硬體功能設定 6. 判斷國內卡錯誤問題 7. 中信T2P顯示錯誤訊息格式問題 更新︰ 中信T2P SDK (3.3 -> 3.6) | 0.3.1 |
| 4.3.6 | 2024-07-10 | 2024-07-18 | 新增︰ Cross App驗證itemList條件 | 0.3.2 |
| 4.3.8 | 2024-07-24 | 2024-07-29 | 新增︰ Cross App TAP退款功能 修正︰ 1. TAP交易錯誤時未回傳300錯誤碼問題 2. 照機的選擇為先後鏡頭再前鏡頭 3. 結帳報表金額計算問題 4. 同步設備交易資料錯誤問題 5. 600交易無法在金流訂單列頁中查詢到資料問題 6. 開啟掃碼頁閃退問題 | 0.3.3 |
| 4.5.0 | 2024-08-30 | 修正︰ 1. 中信T2P code與msg為空問題 2. 中信T2P使用者取消問題 3. D3 MINI上無法使用TAP交易問題 4. TAP交易完成時設備無印表機卡住問題 | 0.3.3 | |
| 4.5.1 | 2024-09-09 | 2024-09-06 部分部署 | 快速修正︰ 重印信用卡簽單失敗問題 | 0.3.3 |
| 4.6.0 | 2024-09-23 | 2024-09-23 部分部署 | 新增︰ Log紀錄功能 更新︰ 中信T2P SDK (橫版轉向問題) | 0.3.3 |
| 4.6.1 | 2024-09-27 | 2024-10-01 | 新增︰ 測試版本的logo背景圖 修正︰ 1. 退款參數uid或key錯誤時的錯誤訊息 2. 收據管理頁儲存圖片時找不到檔案路徑問題 | 0.3.3 |
| 4.6.3 | 2024-10-08 | 更新︰ 測試版app launcher icon 刪除︰ 收據管理頁判斷權限的部分 | 0.3.3 | |
| 4.7.0 | 2024-11-07 | 新增︰ 1. 後開立發票功能(20241112_1、20241112_2)、20241112_3) 2. 發票開立設定頁 3. 結帳報表非當天發立發票計算 | 0.3.4 | |
| 4.7.3 | 2024-11-22 | 新增︰ 1. Cross App TAP交易與退款驗證參數 2. 雲端API呼叫TAP交易與退款功能 3. Cross App裝置設定功能 4. Cross App會員API設定功能 5. Cross App會員累扣點功能 6. Cross App使用優惠券功能 修正︰ 1. 交易成功,列印失敗為成功碼(20241122_1) 2. 退款成功,列印失敗為成功碼(20241122_1) 3. 交易成功,發票配號失敗為成功碼(20241122_1) 4. 交易成功,開立發票失敗為成功碼(20241122_1) 5. Cross App與雲端API呼叫退款orderId為必要參數(20241122_2) 更新︰ 中信T2P測試環境SDK | 0.3.5 | |
| 4.8.0 | 2024-12-09 | 新增︰ 離線自行收款功能 修正︰ 1. 雲端印表機相關問題 2. 當交易不開發票時金流交易API回傳發票空白資訊覆蓋問題 3. Cross App TAP交易開立離線發票成功時回傳204問題 | 0.3.5 | |
| 4.8.1 | 2024-12-19 | 新增︰ 1. log紀錄App版本號 2. Cross訂單明細頁顯示統編資訊 修正︰ 1. 交易請求有統編的發票卻印出一般發票問題 2. Event與Printer卡住問題 | 0.3.5 | |
| 4.8.3 | 2025-01-17 | 2025-01-17 | 快速修正︰ 會員API呼叫失敗相關問題 更新︰ 中信T2P SDK (UAT & Prod) | 0.3.5 |
| 4.9.0 | 2025-02-19 | 2025-02-20 | 新增︰ 1. 交易查詢的log紀錄 2. 自行收款中斷交易時可手動查詢流程 3. TAP交易完成顯示訊息的dialog 4. Cross App依照AppType進行畫面轉向功能 5. 39Buy登入回傳相關資訊 修正︰ 1. 自行收款排除在中斷交易流程之外 2. 網路呼叫刷卡機的log紀錄 | 0.3.5 |
| 5.0.2 | 2025-04-24 | 新增︰ 1. 訂單發票管理功能 2. 金流網路呼叫刷卡機log紀錄 3. 點餐單log紀錄 修正︰ 網路呼叫刷卡機log紀錄 | 0.3.5 | |
| 5.2.1 | 2025-06-12 | 新增︰ 1. 發票自動取號模式 2. 交易成功回傳線上與設備發票剩餘張數 3. 區分iMin的Driver程式 4. 支授Swift 2 Pro printer 5. log紀錄多tag欄位 6. 阻擋同時間多次動作機制 7. 阻擋重複交易機制 8. 設備發票張數低於10張時交易結束時跳出警示的dialog 9. 網路呼叫刷卡機支援經銷商交易與退款 10. App Migration機制 修正︰ 1. 印表機優先權為選擇該印表機時其它類型的印表機不會有作用 2. 印表機設定頁測試列印後按鈕disable問題 3. 部分文字說明 4. 登入時選擇不記住帳密進行動作時會顯示使用錯誤的storeUid問題 5. 修正登入時選擇記住帳密在登出後卻清空問題 | 0.3.5 | |
| 5.2.2 | 2025-06-18 | 2025-06-19 | 修正︰ 登入時選擇記住帳密在登出後卻清空問題 | 0.3.5 |
| 5.4.2 | 2025-08-19 | 2025-08-25 | 新增︰ 1. 設備綁定功能 2. Cross App支援經銷商模式 3. 訂單明細頁顯示授權碼 4. 訂單明細頁支援重新顯示TAP交易QR Code、重補印發票與交易明細功能 修正︰ 1. 結帳報表上補開發票張數錯誤問題 2. 結帳報表區間沒有包含到秒的問題 3. 訂單明細頁更新訂單資訊按鈕條件與使用錯誤的userId查無資料問題 4. 網路呼叫刷卡機交易無法印出交易明細問題 | 0.3.5 |
MYPAY TAP APP
| 版本號 | 測試更新日期 | 正式更新日期 | 異動 | 對應Lib版本 |
|---|---|---|---|---|
| 3.2.0 | 2022-08-10 | 修正︰ 1. app launcher icon 2. SDK初始化錯誤問題 | 0.1.8 | |
| 3.2.1 | 2022-08-23 | 0.1.8 | ||
| 3.2.2 | 2022-08-31 | 修正︰ 1. TAP交易無紀錄itemList與orderTime問題 2. Cross App金流訂單列表與明細頁顯示TAP交易資料問題 | 0.1.8 | |
| 3.2.5 | 2022-09-12 | 新增︰ 1. Device ID資訊頁面 2. Cross App點餐單列表功能 3. Cross App發票管理功能 4. Cross App收據管理功能 5. Cross App印表機設定功能 6. Cross App交易回傳設定功能 7. 交易回傳結果多回傳一碼付echo 修正︰ 1. 非卡機之一般裝置停在App進入頁問題 2. 印表機設定頁測試列印問題 3. 發票列印左右QR Code大小問題 4. QR Code線上交易頁QR Code位置 5. QR Code線上交易無發票時回應280問題 6. 部分頁面隱藏鍵盤問題 | 0.1.9 | |
| 3.5.2 | 2023-03-28 | 2023-03-28 | 新增︰ 1. Cross App一卡通交易功能 2. Cross App結班設定功能 3. 處理錯誤device id機制 4. 阻擋螢幕截圖功能 5. Device資訊頁可確認設備型號 6. 加密App敏感性資料 7. DB Migration進度更新頁面與流程 8. 驗證使用者輸入資料,並於輸入資料正確後才可點擊按鈕進行後續動作 9. 登入頁可選紀錄登入資訊 10. 特店金鑰過期提示 11. 支援一碼付合作夥伴API流程 12. Cross App取得特店支援的支付方式功能 13. 處理國外信用卡交易流程與警示 14. Cross App金流QR Code線上交易支援悠遊付 15. 金流訂單明細頁可更新交易狀態按鈕 16. 金流訂單明細頁顯示發票類型 17. Cross App結帳報表功能 修正︰ 1. 交易回傳結果一碼付echo名稱問題 2. 訂單明細頁右方資料顯示問題 3. Cross App金流交易無法列印免用統一發票收據與農漁民收據問題 4. Cross App一卡通交易使用單一action 5. Cross App一卡通快速與離線詢卡未顯示錯誤訊息問題 6. Cross App一卡通連線詢卡未判斷order id問題 (不向下相容) 7. K2 MINI上掃描使用相機問題 8. 登入頁在部分設備上無法捲動問題 9. 未先登入MYPAY APP無顯示錯誤訊息問題 10. 發票字軌設定相關頁面無法捲動問題 11. 下拉式選單項目太小點擊異常問題 12. 登入頁輸入商務代號與登入帳號為可隱碼 13. 交易查詢改為先查詢Local DB資料而後才為Server端的資料 14. Cross App參數錯誤相對應的錯誤訊息 15. 判斷發票可列印的條件 16. 部分交易無法列印免用統一發票收據與農漁民收據問題 17. QR Code線上交易使用雲端發票參數卻會印出發票問題 18. QR Code線上交易列印發票錯誤問題 19. Local DB紀綠deviceId、一碼付echo、itemList為空值問題 20. 金流訂單列表頁以發票號碼查詢無包含時間條件問題 21. 金流訂單列表頁以發票號碼查詢無資料問題 22. 金流訂單明細頁參數錯誤時還可進行退款問題 23. 一碼付合作夥伴交易回傳條件 24. Cross App金流退款未傳入invoiceState參數問題 25. Local DB無交易時無法退款問題 26. 無法重印國外信用卡簽單問題 27. Cross App訂單查詢資料未完整問題 28. 收據管理頁無法拍照問題 29. 金流訂單明細頁訂單管理功能可使用條件 30. 印表機設定頁與API設定頁儲存和清除資料問題 31. Device資訊頁Android 10以上設備閃退問題 32. 金流交易與訂單明細頁可列印發票條件 33. 金流退款時發票選項為作廢 34. Cross App 39Buy登入頁鍵盤問題 35. Cross App取得特店支援的支付方式問題 更新︰ 1. 保留Local DB交易區間(半年 -> 1個月) 2. 取得發票數量位數(4 -> 3) 3. 頁面名稱 (交易回傳設定 -> 合作夥伴URL設定) 4. MYPAY logo背景圖片 5. 新增發票區間頁與取得發票號碼頁UI | 0.2.7 |
| 3.7.1 | 2023-06-15 | 2023-06-15 | 修正︰ 1. QR Code線上交易頁面無法捲動問題 2. ViewUtils在Service顯示Toast會閃退問題 3. 39Buy取得商品明細缺少uid問題 更新︰ MYPAY訂單管理UI與搜尋功能 | 0.2.7 |
| 3.8.1 | 2023-08-02 | 2023-08-04 | 新增︰ 1. 一卡通回傳金流交易流程 2. 結帳報表頁結帳時處理一卡通結班流程 3. TAP快速更新Token流程 修正︰ 1. 金流訂單列表頁顯示一卡通退款失敗訊息 2. 一卡通交易儲存Local DB的資料格式 3. 商米M2 MAX上一碼付登入時停在主頁面問題 4. 信用卡交易頁面取消時回傳不正確的錯誤碼問題 5. 商米取得SN的程式 6. 取得閘道資料解析錯誤問題 7. TAP回傳金流交易流程 更新︰ 39Buy登入頁登入權限 刪除︰ 信用卡交易頁面顯示卡號與到期日的UI | 0.2.7 |
| 3.9.2 | 2023-09-27 | 2023-10-05 | 新增︰ Cross App 39Buy登入回傳device id (20230927_1) 修正︰ 1. 無法取得Provider問題 2. Cross App取得特店支援的支付方式為設備支援的支付方式(20230927_2) 3. TAP回傳與同步金流交易流程 4. TAP訂單明細頁訂單管理功能可使用條件 | 0.2.8 |
| 4.0.1 | 2023-12-27 | 新增︰ 1. Cross App 39Buy登入回傳device id (20230927_1) 2. 發票字軌設定頁可切換發票開立模式 3. 發票區間列表頁 4. 離線發票開立功能 5. Cross App金流交易使用發票時驗證統一編號、手機載具、自然人憑證 6. 設備取得發票號碼只能是當月或下個月的限制 7. API呼叫可處理網路錯誤問題 修正︰ 1. 無法取得Provider問題 2. Cross App取得特店支援的支付方式為設備支援的支付方式(20230927_2) 3. TAP回傳與同步金流交易流程 4. TAP訂單明細頁訂單管理功能可使用條件 5. 一卡通同步金流相關問題 6. Cross App重印簽單多印一張問題 7. 藍牙設定頁Android 12以上設備閃退問題 8. 列印發票QR Code大小與商品資料過多問題 9. JobService無法執行問題 10. 更新交易發票資訊API參數錯誤問題 11. 判斷商米印表機是否可用的條件 | 0.2.8 | |
| 4.0.3 | 2024-01-17 | 新增︰ 1. Cross App支援全盈支付線上和全支付線上 2. 一碼付切換使用者處理流程 修正︰ 1. Cross Page使用錯誤的storeUid或userId未顯示錯誤訊息問題 2. userId驗證條件 3. 網路呼叫刷卡機重印簽單閃退問題 | 0.2.9 | |
| 4.0.5 | 2024-02-07 | 新增︰ 1. 自行收款設定頁面 2. Cross App取得自行收款設定 3. 發票開立模式設定頁 4. Flutter掃碼頁 修正︰ 先登入MYPAY APP再登入一碼付流程問題 更新︰ 發票字軌設定頁UI | 0.3.0 | |
| 4.0.6 | 2024-02-23 | 新增︰ 藍牙掃碼傳輸功能 | 0.3.1 | |
| 4.2.0 | 2024-04-16 | 新增︰ 1. 信用卡閘道設定錯誤提示訊息 2. 讀卡錯誤提示訊息 3. 12CM會員相關功能 4. Device資訊頁可確認Provider與EMV模組、印表機、掃描器是否可用資訊 修正︰ 1. 一碼付重登入未更新特店金鑰問題 2. 列印自行收款明細問題 3. 交易無法列印免用統一發票收據與農漁民收據問題 4. 呼叫API前判斷金鑰過期流程 5. 金流訂單列表頁查詢一個月以上交易無反應問題 6. 信用卡交易使用手機載具會列印出發票問題 7. 行動支付頁左上返回鍵點下無反應問題 8. 掃碼收款取消掃碼時會出現無法顯示Dialog錯誤問題 9. 照機頁按下拍照後閃退問題 10. 藍牙串接無法退款問題 11. Tap交易使用中信T2P 12. 判斷商米EMV模組是否可用條件 更新︰ 顯示特店金鑰為前4後4碼 | 0.3.1 | |
| 4.2.2 | 2024-05-02 | 新增︰ 1. 商米Printer錯誤時顯示錯誤碼與錯誤訊息 2. 中信加殼設定 3. 中信取消或退款失敗時重新執行另一動作流程 4. 回報結帳交易流程 修正︰ 1. AndroidManifest支援的硬體功能設定 2. 判斷國內卡錯誤問題 3. 中信T2P顯示錯誤訊息格式問題 4. 會員API錯誤碼對應問題 更新︰ 中信T2P SDK (3.3 -> 3.6) | 0.3.1 | |
| 4.3.2 | 2024-06-13 | 新增︰ 1. 中信T2P交易完成後開立線上發票流程 2. 中信T2P重新啟用流程 3. Invoice紀錄發票開立模式 4. 發票線下開立模式切換線上開立模式時尚有號碼提示訊息 5. 取號時必須為線下開立模式提示訊息 6. 金流訂單明細頁更新交易狀態時自動依條件選擇單筆或多筆API查詢 修正︰ 1. 中信T2P交易流程問題 2. 中信T2P交易非數字回傳碼解析錯誤問題 3. 中信T2P交易回傳閘道錯誤碼而非金流狀態碼問題 4. 自行收款設定頁儲存後列表不會更新問題 5. 合作夥伴交易回傳時發票字軌與號碼沒有分開問題 6. 發票字軌轉換格式時未強制大寫問題 7. 線下開立模式時雲端發票未產生對應的列印資料問題 8. 商米印表機在V3 MIX無法取得driver問題 9. 商米印表機在V3 MIX列印空行與圖片問題 10. 信用卡交易使用者取消時顯示錯誤訊息問題 11. 金流訂單明細頁可更新交易狀態按鈕條件 更新︰ 中信加殼設定支援AAB格式 | 0.3.1 | |
| 4.3.4 | 2024-06-21 | 新增︰ 中信T2P正式環境加殼設定 修正︰ 1. 自行收款的對應 2. 中信T2P測試環境加殼設定 3. 中信T2P交易沒有回傳卡別資訊問題 4. 中信T2P退款重新啟用錯誤問題 5. 中信T2P在有API設定頁有輸入URL時沒有回傳交易或退款結果 6. 藍牙模式、瀏覽器模式無法使用TAP交易與Cross Page問題 7. 金流訂單明細頁顯示遮碼卡號 8. 金流訂單明細頁更新交易資料loading不會停止問題 | 0.3.1 | |
| 4.3.5 | 2024-06-27 | 2024-06-29 | 新增︰ 1. Cross App訂單明細功能 2. 訂單明細頁中信T2P退款後會回傳ActionDetails結果 修正︰ 1. D3 MINI上列印單據切斷問題 2. 退款流程更新資料錯誤問題 | 0.3.2 |
| 4.3.7 | 2024-07-16 | 新增︰ 1. Cross App驗證itemList條件 2. Cross App TAP退款功能 | 0.3.3 | |
| 4.4.0 | 2024-08-01 | 新增︰ 中信T2P大特店交易模式流程 修正︰ 1. TAP交易錯誤時未回傳300錯誤碼問題 2. 照機的選擇為先後鏡頭再前鏡頭 3. 結帳報表金額計算問題 4. 同步設備交易資料錯誤問題 5. 600交易無法在金流訂單列頁中查詢到資料問題 6. 開啟掃碼頁閃退問題 7. 中信T2P code與msg為空問題 8. 中信T2P使用者取消問題 | 0.3.3 | |
| 4.4.1 | 2024-08-09 | 修正︰ D3 MINI上無法使用TAP交易問題 | 0.3.3 | |
| 4.4.3 | 2024-08-23 | 修正︰ TAP交易完成時設備無印表機卡住問題 | 0.3.3 | |
| 4.5.2 | 2024-09-09 | 更新︰ 中信T2P SDK (橫版轉向問題) | 0.3.3 | |
| 4.6.3 | 2024-10-08 | 新增︰ 1. Log紀錄功能 2. 測試版本的logo背景圖 修正︰ 1. 退款參數uid或key錯誤時的錯誤訊息 2. 收據管理頁儲存圖片時找不到檔案路徑問題 刪除︰ 收據管理頁判斷權限的部分 | 0.3.3 | |
| 4.6.4 | 2024-11-01 | 修正︰ 中信T2P SDK退回舊版 | 0.3.3 | |
| 4.7.1 | 2024-11-12 | 2024-11-13 | 新增︰ 1. 後開立發票功能(20241112_1、20241112_2)、20241112_3) 2. 發票開立設定頁 3. 結帳報表非當天發立發票計算 更新︰ 中信T2P測試與正式環境SDK | 0.3.4 |
| 4.7.3 | 2024-11-22 | 新增︰ 1. Cross App TAP交易與退款驗證參數 2. 雲端API呼叫TAP交易與退款功能 3. Cross App裝置設定功能 4. Cross App會員API設定功能 5. Cross App會員累扣點功能 6. Cross App使用優惠券功能 修正︰ 1. 交易成功,列印失敗為成功碼(20241122_1) 2. 退款成功,列印失敗為成功碼(20241122_1) 3. 交易成功,發票配號失敗為成功碼(20241122_1) 4. 交易成功,開立發票失敗為成功碼(20241122_1) 5. Cross App與雲端API呼叫退款orderId為必要參數(20241122_2) 更新︰ 中信T2P測試環境SDK | 0.3.5 | |
| 4.8.0 | 2024-12-09 | 新增︰ 離線自行收款功能 修正︰ 1. 雲端印表機相關問題 2. 當交易不開發票時金流交易API回傳發票空白資訊覆蓋問題 3. Cross App TAP交易開立離線發票成功時回傳204問題 | 0.3.5 | |
| 4.8.1 | 2024-12-19 | 新增︰ 1. log紀錄App版本號 2. Cross訂單明細頁顯示統編資訊 修正︰ 1. 交易請求有統編的發票卻印出一般發票問題 2. Event與Printer卡住問題 | 0.3.5 | |
| 4.8.2 | 2024-12-25 | 更新︰ 中信T2P SDK (UAT & Prod) | 0.3.5 | |
| 4.8.3 | 2025-01-02 | 2025-01-02 | 快速修正︰ 會員API呼叫失敗相關問題 | 0.3.5 |
| 4.8.4 | 2025-01-17 | 2025-02-03 | 新增︰ 1. 交易查詢的log紀錄 2. 自行收款中斷交易時可手動查詢流程 3. TAP交易完成顯示訊息的dialog 修正︰ 1. 自行收款排除在中斷交易流程之外 2. 網路呼叫刷卡機的log紀錄 | 0.3.5 |
| 4.9.1 | 2025-03-05 | 新增︰ 1. Cross App依照AppType進行畫面轉向功能 2. 39Buy登入回傳相關資訊 修正︰ 1. 結帳報表沒有計算到TAP信用卡問題 2. 瀏覽器模式無後續動作問題 | 0.3.5 | |
| 5.0.0 | 2025-04-16 | 新增︰ V3 MIX外接商米雲印表機列印發票功能 修正︰ 簽名頁閃退問題 | 0.3.5 | |
| 5.0.3 | 2025-05-16 | 新增︰ 1. 訂單發票管理功能 2. 金流網路呼叫刷卡機log紀錄 3. 點餐單log紀錄 4. 發票自動取號模式 5. 交易成功回傳線上與設備發票剩餘張數(20250516_1、20250516_2) 修正︰ 1. 網路呼叫刷卡機log紀錄 2. 新版中信SDK進入交易頁面S003權限錯誤問題 3. TAP交易完成後如果有設備發票時先同步資料再列印發票流程問題 更新︰ 中信T2P SDK (UAT & Prod) | 0.3.5 | |
| 5.1.5 | 2025-06-03 | 新增︰ 1. V3 MIX外接商米雲印表機列印交易明細、退款收據功能 2. log紀錄多tag欄位 3. 阻擋同時間多次動作機制 4. 阻擋重複交易機制 5. 設備發票張數低於10張時交易結束時跳出警示的dialog 6. 發送T2P log功能 修正︰ 1. 印表機優先權為選擇該印表機時其它類型的印表機不會有作用 2. 印表機設定頁測試列印後按鈕disable問題 3. 部分文字說明 4. 中信T2P交易結果成功條件卡號與授權碼必須有值 | 0.3.5 | |
| 5.2.0 | 2025-06-06 | 新增︰ 網路呼叫刷卡機支援經銷商交易與退款 修正︰ 藍牙串接使用TAP相關action驗證錯誤問題 | 0.3.5 | |
| 5.2.1 | 2025-06-12 | 新增︰ App Migration機制 修正︰ 登入時選擇不記住帳密進行動作時會顯示使用錯誤的storeUid問題 | 0.3.5 | |
| 5.2.2 | 2025-06-18 | 2025-06-19 | 修正︰ 登入時選擇記住帳密在登出後卻清空問題 | 0.3.5 |
| 5.3.0 | 2025-07-03 | 新增︰ 設備綁定功能 | 0.3.5 | |
| 5.3.1 | 2025-07-04 | 2025-07-22 | 修正︰ 1. 結帳報表上補開發票張數錯誤問題 2. 部分錯誤 | 0.3.5 |
| 5.4.0 | 2025-07-31 | 新增︰ Cross App支援經銷商模式(20250731) 修正︰ 1. 結帳報表區間沒有包含到秒的問題 2. 網路呼叫刷卡機TAP交易沒有回傳echo值問題 | 0.3.5 | |
| 5.4.1 | 2025-08-15 | 新增︰ 1. 訂單明細頁顯示授權碼 2. 訂單明細頁支援重新顯示TAP交易QR Code、重補印發票與交易明細功能 3. TAP交易時顯示提示建立連線與登入的dialog 修正︰ 1. 訂單明細頁更新訂單資訊按鈕條件與使用錯誤的userId查無資料問題 2. 網路呼叫刷卡機交易無法印出交易明細問題 | 0.3.5 | |
| 5.4.3 | 2025-08-20 | 新增︰ iMin Swift 2 Pro支援列印結帳報表、免用統一發票收據與農漁民收據 | 0.3.5 | |
| 5.4.4 | 2025-08-25 | 2025-09-01 | 新增︰ Cross App支援TAP初始化動作(20250825_1、20250825_2) 修正︰ TAP初始化提示文字與UI | 0.3.6 |
| 5.4.5 | 2025-09-16 | 2025-09-16 | 快速修正︰ Web與藍牙串接傳送請求後卡住問題 | 0.3.6 |






