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 經銷商代收費
is_agent_charge 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 交易驗証碼 必填
reimbursement_date 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 支付寶
WECHAT 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 支付寶
WECHAT 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 email E-Mail 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 invoiceNo 發票號碼 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_2:交易成功,列印失敗
9999_3:退款成功,列印失敗
9999_4:交易中斷
9999_5:查詢的交易不存在
9999_6:取消登入(39Buy)
9999_7:掃碼錯誤
9999_8:取消感應票卡
9999_9:尚未設定合作夥伴的URL
9999_10:請先安裝xxx APP
9999_11:交易成功,發票配號失敗
9999_12:一碼付切換使用者
9999_13:交易成功,開立發票失敗
此部分的錯誤請依對應的情況進行處理︰
9999_1:此動作為使用者自行決定的動作,即手動取消,如果已發動交易,MYPAY APP將會在背景進行退款動作,以避免同一訂單進行多次交易的情況發生
9999_2:表示交易成功,只需重新列印缺少的單據,無須重新交易
9999_3:表示退款成功,只需重新列印缺少的單據,無須重新交易
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
WECHAT 微信支付線上 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 微信支付線上 WECHAT
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測試流程

直接交易

  1. 從應用市場中安裝最新版本的MYPAY APP。
  2. 進入MYPAY APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。
  3. 離開MYPAY APP,並在串接方App中將資料傳入MYPAY APP進行動作。

TAP交易(只有MYPAY TAP APP支援)

  1. 從應用市場中安裝最新版本的MYPAY TAP APP。
  2. 進入MYPAY TAP APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。
  3. 離開MYPAY TAP APP,並在串接方App中將資料傳入MYPAY TAP APP進行動作。

一卡通交易(Lib 0.2.0)

  1. 從應用市場中安裝最新版本的MYPAY APP。
  2. 進入MYPAY APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。
  3. 離開MYPAY APP,並在串接方App中將資料傳入MYPAY APP進行動作。

其它動作(Lib 0.1.5)

  1. 從應用市場中安裝最新版本的MYPAY APP。
  2. 進入MYPAY APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。
  3. 離開MYPAY APP,並在串接方App中將資料傳入MYPAY APP進行動作。

MYPAY頁面(Lib 0.1.8)

  1. 從應用市場中安裝最新版本的MYPAY APP。
  2. 進入MYPAY APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。
  3. 離開MYPAY APP,並在串接方App中將資料傳入MYPAY APP進入指定的頁面。

39Buy交易(Lib 0.0.56)

  1. 從應用市場中安裝最新版本的MYPAY APP。

  2. 進入MYPAY APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。

  3. 離開MYPAY APP,在串接方App中將資料傳入MYPAY APP進行手動登入,取得token。

  4. 每次對MYPAY APP進行動作時須將appToken傳入。

  5. 若MYPAY APP返回token無效的錯誤,請再重新手動登入以取得新的token,再進行其它動作。

    藍牙串接 (APP v3.9.0)

  6. 從應用市場中安裝最新版本的MYPAY APP。

  7. 進入MYPAY APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。

  8. 串接方使用的裝置和已安裝MYPAY APP的設備配對藍牙。

  9. 將藍牙傳輸設定頁面中確認的藍牙串接ID加入串接方程式。

  10. 離開MYPAY APP (Android 11以上的設備,請開啟MYPAY APP,若關閉APP,可能會有收到不請求的問題),在串接方程式中將資料加密並透過藍牙傳入MYPAY APP進行動作。

    瀏覽器串接 (APP v3.9.1)

  11. 從應用市場中安裝最新版本的MYPAY APP。

  12. 進入MYPAY APP進行登入,並確認登入是否成功(登入成功會看到上方有商店名稱,下方有登出的按鈕)。

  13. 離開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_120230901_2)
0.2.7
3.9.1 2023-09-06 新增︰
Web串接MYPAY APP功能(20230906_120230906_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_120241112_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_120241112_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_120250516_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_120250825_2)

修正︰
TAP初始化提示文字與UI
0.3.6
5.4.5 2025-09-16 2025-09-16 快速修正︰
Web與藍牙串接傳送請求後卡住問題
0.3.6