NAV
php csharp java javascript python

修改歷程

版本 異動日期 修訂內容 位置
1.0 2021.01.01 新版文件
1.0.1 2023.02.08 調整信用卡授權請款說明 20230208_01

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://pay.usecase.cc/api/agent
正式區 https://mypay.tw/api/agent

Client模式(限定功能)

位置 API介接網址
測試區 https://pay.usecase.cc/api/open
正式區 https://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://pay.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://pay.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://pay.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://pay.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://pay.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_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 預選付費方法 『付款方式』值參考
interface string interface 對照表
discount string 折價金額 (預設0)
success_returl string 交易成功導頁網址
failure_returl string 交易失敗導頁網址
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_m_post_zone string EMail 紙本寄送郵遞區號 當invoice_cloud_type為4,此欄位才有效,非必須
invoice_m_address string EMail 紙本寄送住址 當invoice_cloud_type為4,此欄位才有效,非必須
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 信用卡類交易時,是否使用授權請款模式(預設自動請款) 『信用卡授權請款模式類型』值參考
creditcard_invoice string 信用卡授權請款模式有調整為自行請款模式時,若有開立發票,開立發票時機 『信用卡發票開立模式』值參考

『PayPage金流交易』回傳欄位

參數名稱 型態 說明 必須
code string 交易回傳碼
msg string 回傳訊息
uid string 訂單之交易流水號(交易訂單/票券服務訂單/儲值訂單)
key string 交易驗証碼
url string 交易網址
支援語系名稱 語系編碼
繁體中文版 zh-TW(預設)
簡體中文版 zh-CN
英文版 en

『交易完成回傳資訊』回報欄位

參數名稱 型態 說明 必須
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 發卡銀行代碼
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 發卡銀行代碼
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 發卡銀行代碼
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://pay.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://pay.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://pay.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://pay.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://pay.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",
    "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 發卡銀行代碼
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

發動交易後,如果遲遲未接收回報,可透過此方法查詢訂單交易。

交易退款

<?php
/**
 * 經銷商串接-交易退款
 */
final class AgentRefund
{
    /**
     * 經銷商商務代號
     * @var string
     */
    public $agentUid = "518169081001";
    /**
     * 經銷商金鑰或認證碼
     * @var string
     */
    public $agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
    /**
     * 特約商店商務代號(代特約商店發動)
     * @var string
     */
    public $storeUid = "289151880002";
    /**
     * 串接交易位置
     * @var string
     */
    public $url = "https://pay.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://pay.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://pay.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://pay.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://pay.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 退款項目
若使用電子發票,此欄位必填
退款項目之項目名稱必須和交易時之產品項目名稱相同
退款項目之總金額必須與退款金額一致
每筆『商品項目』欄位參考

『交易退款』回傳欄位

參數名稱 型態 說明 必須
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://pay.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://pay.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://pay.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://pay.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://pay.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_m_post_zone": "",
        "invoice_m_address": "",
        "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://pay.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' => '1',
                                 'amount' => '1',
                                 'total' => '1'
                                ]
                            ];

        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://pay.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 = "1";
            item.amount = "1";
            item.total = "1";
            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://pay.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", "1");
        item.put("amount", "1");
        item.put("total", "1");
        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://pay.usecase.cc/api/agent";
};
/**
 * 取得串接欄位資料
 */
AgentCreditcardRequestPayment.prototype.getRawData = function () {
    return {
        store_uid: this.storeUid,
        uid: "103283",
        key: "54886f30612771f8f10d94499a41a347",
        cost: 9,
        items: [
                   {
                    'id': "1",
                    'name': "商品名稱",
                    'cost': "1",
                    'amount': "1",
                    'total': "1"
                   }
               ],

    };
};
/**
 * 取得服務位置
 */
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://pay.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': "1",
                          'amount': "1",
                          'total': "1"
                         }
                     ],
        }
        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_m_post_zone": "",
        "invoice_m_address": "",
        "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.非代收付特約商店:依據不同銀行,天數不同,請參考下表,如不再此表內的銀行,請自行與銀行確認

銀行名稱 天數
中國信託 7天
永豐銀行 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 不想請款的產品項目(商品名稱必須與原交易時商品名稱相同)
如果部分金額不想請款才需要使用,也就是說如果原訂單金額是100,只想請款40,那不想請款的那60元必須代入
每筆『商品項目』欄位參考

『信用卡授權請款』回傳欄位

參數名稱 型態 說明 必須
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://pay.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://pay.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://pay.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://pay.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://pay.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://pay.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 protected]";
        $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://pay.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 protected]";
            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://pay.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 protected]");
        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://pay.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://pay.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:\/\/pay.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://pay.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://pay.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://pay.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://pay.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://pay.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://pay.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://pay.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://pay.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://pay.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://pay.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)
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_m_post_zone string EMail 紙本寄送郵遞區號 當invoice_cloud_type為4,此欄位才有效,非必須
invoice_m_address string EMail 紙本寄送住址 當invoice_cloud_type為4,此欄位才有效,非必須
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://pay.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://pay.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://pay.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://pay.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://pay.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

代收款核銷撥款請求

使用情境:當經銷商經營平台服務,為確保產品或服務已經交付完畢後,款項才撥付給特約商店時使用。

註:消費者若已退款,也必須發動核銷

<?php
/**
 * 經銷商串接-代收款核銷撥款請求
 */
final class AgentRequestPayment
{
    /**
     * 經銷商商務代號
     * @var string
     */
    public $agentUid = "518169081001";
    /**
     * 經銷商金鑰或認證碼
     * @var string
     */
    public $agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
    /**
     * 特約商店商務代號(代特約商店發動)
     * @var string
     */
    public $storeUid = "289151880002";
    /**
     * 串接交易位置
     * @var string
     */
    public $url = "https://pay.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 可能沒