NAV
php csharp java javascript python

MYPAY電子錢包交易設計概要

安全性設計

所有的要求發動都僅能從特約商店的網頁伺服器發出請求,將傳輸的資料以AES加密,再透過HTTPS加密傳輸。交易資料不由消費者端送出,可確保資料不被消費者竄改。所有付費資訊經過MYPAY Link匝道進行轉送處理,特約商店不需要處理消費者的付費流程以及安全控管。

MYPAY 目前提供之服務與格式

MYPAY電子錢包交易:

(1)MYPAY電子錢包綁定:發動電子錢包綁定,消費者在MYPAY綁定電子錢包後,經銷商接收虛擬卡號。

(2)MYPAY電子錢包交易:透過虛擬卡號,發動電子錢包交易。

(3)MYPAY電子錢包請款取消授權:電子錢包交易極為信用卡類型交易,若使用自行請款模式,交易狀態為授權完成(245)時,則可以發動此電子錢包取消授權,用以取消交易,並釋出消費者圈存金額。

(4)MYPAY電子錢包授權請款:電子錢包交易極為信用卡類型交易,若使用自行請款模式,交易狀態為授權完成(245)時,則可以發動此電子錢包授權請款,用以完成交易。 發動只限定一次。可全額或部分請款。

(5)MYPAY電子錢包解除綁定:解除指定帳號電子錢包綁定。

我們提供介接方式是透過https連線,只接受POST方式傳送交易資料。

介接網址

特約商店模式

位置 API介接網址
測試區 https://pay.usecase.cc/api/agent
正式區 https://ka.mypay.tw/api/agent

資料加密方式

AES 256編碼 + base64編碼(附錄四資料加密方式)

加密金鑰

金鑰會透過mail發送,也可從管理後台取得

文字編碼

一律使用UTF-8相容編碼

MYPAY電子錢包綁定

<?php
/**
 * 經銷商串接-MYPAY電子錢包綁定
 */
final class AgentEWalletBind
{
    /**
     * 經銷商商務代號
     * @var string
     */
    public $agentUid = "518169081001";
    /**
     * 經銷商金鑰或認證碼
     * @var string
     */
    public $agentKey = "2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
    /**
     * 特約商店商務代號(代特約商店發動)
     * @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'] = "http://www.mypay.com.tw/";
        $rawData['failure_returl'] = "http://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 = "2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
        /// <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 =  "http://www.mypay.com.tw/";
            rawData.failure_returl =  "http://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');

/**
 * 經銷商串接-MYPAY電子錢包綁定
 */
function AgentEWalletBind() {
    // 經銷商商務代號
    this.agentUid = "518169081001";
    // 經銷商金鑰或認證碼
    this.agentKey = "2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
    // 特約商店商務代號
    this.storeUid = "289151880002";
    // 串接交易位置
    this.url = "https://pay.usecase.cc/api/agent";
};
/**
 * 取得串接欄位資料
 */
AgentEWalletBind.prototype.getRawData = function () {
    return {
        store_uid: this.storeUid,
        user_id: "phper",
        user_sn: "A123456789",
        user_cellphone_code: "886",
        user_cellphone: "918123123",
        user_real_name: "金城武",
        user_email: "[email protected]",
        user_english_name: "Takeshi Kaneshiro",
        user_address: "台中市西區台灣大道二段573號6樓E室",
        pfn: "CREDITCARD",
        ip: "127.0.0.1",
        success_returl: "http://www.mypay.com.tw/",
        failure_returl: "http://www.google.com.tw/",

    };
};
/**
 * 取得服務位置
 */
AgentEWalletBind.prototype.getService = function () {
    return {
        service_name: "api",
        cmd: "api/ewalletbind"
    };
};
/**
 * AES 256 加密
 */
AgentEWalletBind.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 到主機
 */
AgentEWalletBind.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();
    });
};
/**
 * 取得送出欄位資料
 */
AgentEWalletBind.prototype.getPostData = function () {
    return {
        "agent_uid": this.agentUid,
        "service": this.encrypt(this.getService(), this.agentKey),
        "encry_data": this.encrypt(this.getRawData(), this.agentKey)
    };
};
/**
 * 執行
 */
AgentEWalletBind.prototype.run = async function () {
    json = await this.post(this.getPostData())
    console.log(json);
};

AgentEWalletBind = new AgentEWalletBind();
AgentEWalletBind.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

"""經銷商串接-MYPAY電子錢包綁定
"""
class AgentEWalletBind:
    # 經銷商商務代號
    agentUid = "518169081001";
    # 經銷商金鑰或認證碼
    agentKey = b"2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
    # 特約商店商務代號
    storeUid = "289151880002"
    # 串接交易位置
    url = "https://pay.usecase.cc/api/agent"

    def getRawData(self):
        """取得串接欄位資料

        Returns:
            {dict}: 欄位資料
        """
        rawData = {
            'store_uid': self.storeUid,
            'user_id': "phper",
            'user_sn': "A123456789",
            'user_cellphone_code': "886",
            'user_cellphone': "918123123",
            'user_real_name': "金城武",
            'user_email': "[email protected]",
            'user_english_name': "Takeshi Kaneshiro",
            'user_address': "台中市西區台灣大道二段573號6樓E室",
            'pfn': "CREDITCARD",
            'ip': "127.0.0.1",
            'success_returl': "http://www.mypay.com.tw/",
            'failure_returl': "http://www.google.com.tw/",
        }
        return rawData

    def getService(self):
        """取得服務位置

        Returns:
            {dict}: 服務位置資料
        """
        return {
            'service_name': 'api',
            'cmd': 'api/ewalletbind'
        }

    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)

AgentEWalletBind = AgentEWalletBind()
AgentEWalletBind.run()

回傳 JSON 結構如下:

{
    "code": "B200",
    "msg": "執行成功",
    "url": "http:\/\/pay.k20-mypay.tw\/ewallet\/101517.html"
}

特約商店發動MYPAY電子錢包交易綁定,消費者在MYPAY綁定電子錢包後,MYPAY會將綁定的電子錢包虛擬卡號通知特約商店。

特約商店可透過電子錢包虛擬卡號發動交易。消費者若取消電子錢包綁定時,MYPAY也會通知特約商店。

經銷商『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 綁定支付方式 『付款方式』值參考
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.啟用

MYPAY電子錢包交易

<?php
/**
 * 經銷商串接-直接交易-MYPAY電子錢包交易
 */
final class AgentEWallet
{
    /**
     * 經銷商商務代號
     * @var string
     */
    public $agentUid = "518169081001";
    /**
     * 經銷商金鑰或認證碼
     * @var string
     */
    public $agentKey = "2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
    /**
     * 特約商店商務代號(代特約商店發動)
     * @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' => '10',
                                 'amount' => '1',
                                 'total' => '10'
                                ]
                            ];
        $rawData['cost'] = "10";
        $rawData['user_id'] = "phper";
        $rawData['order_id'] = "1234567890";
        $rawData['ip'] = "127.0.0.1";
        $rawData['pfn'] = "EWALLET";
        $rawData['data_json'] = "{\"virtualPan\":\"7b5ba7bf23ca4b3f8bcd11caac5b2de6\",\"userId\":\"phper\",\"bizId\":\"289151880002\"}";

        return $rawData;
    }
    /**
     * 取得服務位置
     * @return array
     */
    public function getService()
    {
        return array(
            'service_name' => 'api',
            'cmd' => 'api/transaction'
        );
    }
    /**
     * 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;
    }
}

$AgentEWallet = new AgentEWallet();
$AgentEWallet->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 AgentEWallet {
        /// <summary>
        /// 經銷商商務代號
        /// </summary>
        public string agentUid = "518169081001";
        /// <summary>
        /// 經銷商金鑰或認證碼
        /// </summary>
        public string agentKey = "2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
        /// <summary>
        /// 特約商店商務代號
        /// </summary>
        public string storeUid = "289151880002";

        /// <summary>
        /// 串接交易位置
        /// </summary>
        public string url = "https://pay.usecase.cc/api/agent";
        /// <summary>
        /// 執行
        /// </summary>
        static void Main() {
            AgentEWallet simulator = new AgentEWallet();
            //僅限走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 = "10";
            item.amount = "1";
            item.total = "10";
            items.Add(item);


            dynamic rawData = new ExpandoObject();
            rawData.store_uid = this.storeUid;
            rawData.items = items;
            rawData.cost =  "10";
            rawData.user_id =  "phper";
            rawData.order_id =  "1234567890";
            rawData.ip =  "127.0.0.1";
            rawData.pfn =  "EWALLET";
            rawData.data_json =  "{\"virtualPan\":\"7b5ba7bf23ca4b3f8bcd11caac5b2de6\",\"userId\":\"phper\",\"bizId\":\"289151880002\"}";

            return rawData;
        }
        /// <summary>
        /// 取得服務位置
        /// </summary>
        private ServiceRequest GetService() {
            ServiceRequest rawData = new ServiceRequest();
            rawData.service_name = "api";
            rawData.cmd = "api/transaction";
            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 AgentEWallet {
    /**
     * 經銷商商務代號
     */
    String agentUid = "518169081001";
    /**
     * 經銷商金鑰或認證碼
     */
    String agentKey = "2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
    /**
     * 特約商店商務代號
     */
    String storeUid = "289151880002";
    /**
     * 串接交易位置
     */
    String url = "https://pay.usecase.cc/api/agent";
    /**
     * 執行
     * @param  args
     */
    public static void main(String[] args) {
        AgentEWallet simulator = new AgentEWallet();
        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> rawData = new HashMap<Object, Object>();
        rawData.put("store_uid", this.storeUid);
        rawData.put("items", items);
        rawData.put("cost", "10");
        rawData.put("user_id", "phper");
        rawData.put("order_id", "1234567890");
        rawData.put("ip", "127.0.0.1");
        rawData.put("pfn", "EWALLET");
        rawData.put("data_json", "{\"virtualPan\":\"7b5ba7bf23ca4b3f8bcd11caac5b2de6\",\"userId\":\"phper\",\"bizId\":\"289151880002\"}");

        return rawData;
    }
    /**
     * 取得服務位置
     * @return 串接服務資料
     */
    public Map getService() {
        Map<Object, Object> rawData = new HashMap<Object, Object>();
        rawData.put("service_name", "api");
        rawData.put("cmd", "api/transaction");
        return rawData;
    }
    /**
     * AES 256 加密
     * @param rawData 原始資料
     * @param AesKey AES256金鑰字串
     * @return 轉換成Base64資料
     */
    public String encrypt(Map rawData, String AesKey) {

        try {
            ObjectMapper objMapper = new ObjectMapper();

            byte[] data = objMapper.writeValueAsString(rawData).getBytes(UTF_8);
            byte[] key = AesKey.getBytes(UTF_8);

            // 16 bytes is the IV size for AES256
            PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
                    new CBCBlockCipher(new AESEngine()));
            // Random iv
            SecureRandom rng = new SecureRandom();
            byte[] ivBytes = new byte[16];
            rng.nextBytes(ivBytes);

            cipher.init(true, new ParametersWithIV(new KeyParameter(key),
                    ivBytes));
            byte[] outBuf = new byte[cipher.getOutputSize(data.length)];

            int processed = cipher
                    .processBytes(data, 0, data.length, outBuf, 0);
            processed += cipher.doFinal(outBuf, processed);

            byte[] outBuf2 = new byte[processed + 16]; // Make room for iv
            System.arraycopy(ivBytes, 0, outBuf2, 0, 16); // Add iv
            System.arraycopy(outBuf, 0, outBuf2, 16, processed);

            Base64.Encoder encoder = Base64.getEncoder();
            String base64 = encoder.encodeToString(outBuf2);
            return base64;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 資料 POST 到主機
     * @param qstr 串接資料
     * @return 服務回傳JSON資訊
     */
    public String post(String qstr) {
        String result = "";
        try {
            // 資料
            byte[] qstr_bytes = qstr.getBytes(StandardCharsets.UTF_8);

            URL iurl = new URL(this.url);
            SSLContext sc = SSLContext.getInstance("TLSv1.2"); // $NON-NLS-1$
            sc.init(null, null, new java.security.SecureRandom());

            HttpsURLConnection con = (HttpsURLConnection) iurl.openConnection();
            con.setSSLSocketFactory(sc.getSocketFactory());
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type",
                    "application/x-www-form-urlencoded");
            con.setRequestProperty("Content-Length",
                    String.valueOf(qstr_bytes.length));
            con.setRequestProperty("Accept-Charset", "UTF-8");

            con.setDoOutput(true);
            con.setDoInput(true);

            con.getOutputStream()
                    .write(qstr.getBytes(Charset.forName("UTF-8")));
            con.getOutputStream().flush();

            BufferedReader in = new BufferedReader(new InputStreamReader(
                    con.getInputStream(), "UTF-8"));
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine + "\r\n");
            }

            try {
                result = response.toString();
            } finally {
                in.close();
            }
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
        return result;
    }
    /**
     * 取得送出欄位資料
     * @return POST完整資料
     */
    public String getPostData() {
        String postData = "";
        try {
            // Base64需要使用UrlEncode做傳輸
            String data_toUrlEncode = URLEncoder.encode(
                    this.encrypt(this.getRawData(), this.agentKey), "UTF-8");
            String svr_toUrlEncode = URLEncoder.encode(
                    this.encrypt(this.getService(), this.agentKey), "UTF-8");

            postData = "agent_uid=" + this.agentUid + "&service="
                    + svr_toUrlEncode + "&encry_data=" + data_toUrlEncode;
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
        return postData;
    }
}

const crypto = require('crypto');
const httpRequest = require('https');

/**
 * 經銷商串接-直接交易-MYPAY電子錢包交易
 */
function AgentEWallet() {
    // 經銷商商務代號
    this.agentUid = "518169081001";
    // 經銷商金鑰或認證碼
    this.agentKey = "2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
    // 特約商店商務代號
    this.storeUid = "289151880002";
    // 串接交易位置
    this.url = "https://pay.usecase.cc/api/agent";
};
/**
 * 取得串接欄位資料
 */
AgentEWallet.prototype.getRawData = function () {
    return {
        store_uid: this.storeUid,
        items: [
                   {
                    'id': "1",
                    'name': "商品名稱",
                    'cost': "10",
                    'amount': "1",
                    'total': "10"
                   }
               ],
        cost: "10",
        user_id: "phper",
        order_id: "1234567890",
        ip: "127.0.0.1",
        pfn: "EWALLET",
        data_json: "{\"virtualPan\":\"7b5ba7bf23ca4b3f8bcd11caac5b2de6\",\"userId\":\"phper\",\"bizId\":\"289151880002\"}",

    };
};
/**
 * 取得服務位置
 */
AgentEWallet.prototype.getService = function () {
    return {
        service_name: "api",
        cmd: "api/transaction"
    };
};
/**
 * AES 256 加密
 */
AgentEWallet.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 到主機
 */
AgentEWallet.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();
    });
};
/**
 * 取得送出欄位資料
 */
AgentEWallet.prototype.getPostData = function () {
    return {
        "agent_uid": this.agentUid,
        "service": this.encrypt(this.getService(), this.agentKey),
        "encry_data": this.encrypt(this.getRawData(), this.agentKey)
    };
};
/**
 * 執行
 */
AgentEWallet.prototype.run = async function () {
    json = await this.post(this.getPostData())
    console.log(json);
};

AgentEWallet = new AgentEWallet();
AgentEWallet.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

"""經銷商串接-直接交易-MYPAY電子錢包交易
"""
class AgentEWallet:
    # 經銷商商務代號
    agentUid = "518169081001";
    # 經銷商金鑰或認證碼
    agentKey = b"2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
    # 特約商店商務代號
    storeUid = "289151880002"
    # 串接交易位置
    url = "https://pay.usecase.cc/api/agent"

    def getRawData(self):
        """取得串接欄位資料

        Returns:
            {dict}: 欄位資料
        """
        rawData = {
            'store_uid': self.storeUid,
            'items': [
                         {
                          'id': "1",
                          'name': "商品名稱",
                          'cost': "10",
                          'amount': "1",
                          'total': "10"
                         }
                     ],
            'cost': "10",
            'user_id': "phper",
            'order_id': "1234567890",
            'ip': "127.0.0.1",
            'pfn': "EWALLET",
            'data_json': "{\"virtualPan\":\"7b5ba7bf23ca4b3f8bcd11caac5b2de6\",\"userId\":\"phper\",\"bizId\":\"289151880002\"}",
        }
        return rawData

    def getService(self):
        """取得服務位置

        Returns:
            {dict}: 服務位置資料
        """
        return {
            'service_name': 'api',
            'cmd': 'api/transaction'
        }

    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)

AgentEWallet = AgentEWallet()
AgentEWallet.run()

回傳 JSON 結構如下:

{
    "invoice_state": 0,
    "invoice_state_msg": "不處理",
    "invoice_date": "",
    "invoice_wordtrack": "",
    "invoice_number": "",
    "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_print_type": 0,
    "invoice_print_device": 0,
    "invoice_amount": "",
    "invoice_sales_amount": "",
    "invoice_tax_amount": "",
    "invoice_order_detail": "",
    "invoice_ratetype": 1,
    "invoice_input_type": 0,
    "invoice_cloud_type": 0,
    "invoice_mobile_code": "",
    "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": "",
    "code": "250",
    "msg": "執行成功。",
    "uid": 101520,
    "key": "bca469b4b021feaaaffc2599d8d073e0",
    "finishtime": "20220125095612",
    "cardno": "400361******7729",
    "acode": "929114",
    "card_type": "1",
    "issuing_bank": "中國信託",
    "issuing_bank_uid": "822",
    "transaction_mode": "1",
    "supplier_name": "中國信託商業銀行",
    "supplier_code": "B8",
    "order_id": "1234567890",
    "user_id": "phper",
    "cost": 10,
    "currency": "TWD",
    "actual_cost": 10,
    "actual_currency": "TWD",
    "pfn": "CREDITCARD",
    "trans_type": 1,
    "result_type": 4,
    "result_content_type": "CREDITCARD",
    "result_content": "{\n    \"ACode\": \"929114\",\n    \"TradeNo\": \"101520\",\n    \"Status\": 0,\n    \"OrderTotalCost\": \"10\"\n}",
    "echo_0": "",
    "echo_1": "",
    "echo_2": "",
    "echo_3": "",
    "echo_4": ""
}

當消費者想直接交易時,特約商店可以使用虛擬卡號直接發動MYPAY電子錢包交易,即進行扣款動作。

經銷商『MYPAY電子錢包交易』參數說明

欄位 型態 說明
agent_uid string(16) 經銷商商務代號
service text {"service_name": "api", "cmd": "api\/transaction"}
JSON格式,AES256加密資料
encry_data text 『MYPAY電子錢包交易』欄位參考
JSON格式,AES256加密資料

『直接交易-MYPAY電子錢包交易』欄位

參數名稱 型態 說明 必須
store_uid string 特約商店代碼 必填
cost string 訂單總金額 必填
currency string 預設交易幣別(預設為TWD新台幣)
order_id string 訂單編號 必填
items array 訂單內物品數 每筆『商品項目』欄位參考
echo_0 string 自訂回傳參數 1
echo_1 string 自訂回傳參數 2
echo_2 string 自訂回傳參數 3
echo_3 string 自訂回傳參數 4
echo_4 string 自訂回傳參數 5
pfn string 付費方法 (EWALLET)
discount string 折價金額 (預設0)
shipping_fee 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 必填
issue_invoice_state integer 開立發票 『電子發票是否開立狀態』值參考
invoice_ratetype integer 電子發票稅率別 『電子發票稅率別』值參考
invoice_input_type integer 電子發票開立類型 『電子發票開立類型』值參考
invoice_cloud_type integer 「雲端發票」類型 當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時,此欄位才有效
agent_sms_fee_type integer 經銷商代收費是否含簡訊費 (0.不含 1.含) 『含不含簡訊費』值參考
agent_charge_fee_type integer 經銷商代收費是否含手續費 (0.不含 1.含) 『含不含手續費類型』值參考
agent_charge_fee string 經銷商代收費
is_agent_charge integer 是否為經銷商代收費模式
若 is_agent_charge 有指定,以指定優先
若欄位agent_charge_fee有費用,或經銷商代收費是含簡訊費、或經銷商代收費含手續費,則預設為1
若欄位agent_charge_fee無費用,且經銷商代收費不含簡訊費、或經銷商代收費不含手續費或參欄位都未使用則預設為0
『是否為經銷商代收費模式』值參考
creditcard_is_automatic_payment string 電子錢包交易時,是否使用自動請款模式(預設自動請款)
非所有收單銀行均有配合
『信用卡自動請款類型』值參考
data_json string MYPAY電子錢包格式(JSON格式) 『MYPAY電子錢包資料』值參考

『直接交易-MYPAY電子錢包交易』回傳欄位

參數名稱 型態 說明 必須
code string 交易狀態代碼
msg string 回傳訊息
uid string Payment Hub之交易流水號
key string 交易驗証碼
finishtime string 交易完成時間(YYYYMMDDHHmmss)
cardno string 銀行端口回傳碼
acode string 授權碼
card_type integer 信用卡卡別 『信用卡別類型』值參考
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 實際交易幣別
pfn string 付費方法 『回傳付款方式』值參考
trans_type integer 交易類型 『交易類型定義』值參考
result_type string 回傳結果資料類型 『閘道內容回傳格式類型』值參考
result_content_type string 回傳資料內容類型 『資料內容所屬支付名稱』值參考
result_content string 回傳結果
echo_0 string 自訂回傳參數 1
echo_1 string 自訂回傳參數 2
echo_2 string 自訂回傳參數 3
echo_3 string 自訂回傳參數 4
echo_4 string 自訂回傳參數 5
invoice_state integer 發票開立狀態 『電子發票開立狀態類型』值參考
invoice_state_msg string 發票開立狀態訊息
invoice_date string 發票開立日期(YYYYMMDDHHmmss)
invoice_wordtrack string 發票字軌
invoice_number string 發票號碼
invoice_rand_code string 電子發票隨機碼
invoice_seller_ban string 賣方統一編號
invoice_buyer_ban string 買方統一編號
invoice_left_qrcode string 電子發票左邊QrCode內容
invoice_middle_barcode string 電子發票中間Barcode內容(格式Code-39)
invoice_right_qrcode string 電子發票右邊QrCode內容
invoice_title_type integer 電子發票列印標題格式 『電子發票紙本列印標題類型』值參考
invoice_title string 電子發票列印標題格式
invoice_print_type integer 電子發票列印類型 『電子發票列印類型』值參考
invoice_print_device integer 電子發票列印設備 『電子發票列印設備』值參考
invoice_amount string 電子發票銷售總額
invoice_sales_amount string 電子發票銷售額
invoice_tax_amount string 電子發票稅額
invoice_order_detail string 電子發票全部產品明細(JSON格式) 『商品細項』值參考
invoice_ratetype integer 電子發票稅率別 『電子發票稅率別』值參考
invoice_input_type integer 電子發票開立類型 『電子發票開立類型』值參考
invoice_cloud_type integer 電子發票開立類型-雲端發票類型 『雲端發票類型』值參考
invoice_mobile_code string 當invoice_cloud_type為2時紀錄的手機條碼
invoice_tax_id string 當invoice_cloud_type為2時紀錄的統一編號
invoice_natural_person string 當invoice_cloud_type為3時紀錄的自然人憑證條碼
invoice_m_post_zone string 當invoice_cloud_type為4時紀錄中獎時紙本發票郵遞區號
invoice_m_address string 當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時紀錄的發票地址

MYPAY電子錢包請款取消授權

<?php
/**
 * 經銷商串接-信用卡取消授權
 */
final class AgentCreditcardCancelAuthorized
{
    /**
     * 經銷商商務代號
     * @var string
     */
    public $agentUid = "518169081001";
    /**
     * 經銷商金鑰或認證碼
     * @var string
     */
    public $agentKey = "2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
    /**
     * 特約商店商務代號(代特約商店發動)
     * @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 = "2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
        /// <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 = "2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
    // 特約商店商務代號
    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"2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
    # 特約商店商務代號
    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": ""
  }
}

MYPAY電子錢包請款取消授權,若使用自行請款模式,當交易狀態為授權完成(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 查詢內容 『交易查詢』欄位參考

MYPAY電子錢包授權請款

<?php
/**
 * 經銷商串接-信用卡授權請款
 */
final class AgentCreditcardRequestPayment
{
    /**
     * 經銷商商務代號
     * @var string
     */
    public $agentUid = "518169081001";
    /**
     * 經銷商金鑰或認證碼
     * @var string
     */
    public $agentKey = "2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
    /**
     * 特約商店商務代號(代特約商店發動)
     * @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 = "2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
        /// <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 = "2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
    // 特約商店商務代號
    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"2MrhtRYeF9wKZ4bKwzZoL8aZf26pWzIG";
    # 特約商店商務代號
    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)時,則可以發動此MYPAY電子錢包授權請款,用以完成交易。發動只限定一次。可全額或部分請款。

經銷商『MYPAY電子錢包授權請款』參數說明

欄位 型態 說明
agent_uid string(16) 經銷商商務代號
service text {"service_name": "api", "cmd": "api\/authorizedrequestpayment"}
JSON格式,AES256加密資料
encry_data text 『電子錢包請款取消授權』欄位參考
JSON格式,AES256加密資料

『MYPAY電子錢包授權請款』欄位

參數名稱 型態 說明 必須
store_uid string 特約商店編號 必填
uid string 交易流水號
key string 交易驗証碼
cost integer 總請款金額
items array 不想請款的產品項目(商品名稱必須與原交易時商品名稱相同)
如果部分金額不想請款才需要使用,也就是說如果原訂單金額是100,只想請款40,那不想請款的那60元必須代入
每筆『商品項目』欄位參考

『MYPAY電子錢包授權請款』回傳欄位

參數名稱 型態 說明 必須
code string 交易回傳碼
msg string 回傳訊息
content object 查詢內容 『交易查詢』欄位參考

MYPAY電子錢包解除綁定

<?php
/**
 * 經銷商串接-MYPAY電子錢包解除綁定
 */
final class AgentEWalletDisabler
{
    /**
     * 經銷商商務代號
     * @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['pfn'] = "CREDITCARD";
        $rawData['reason'] = "系統自動取消";

        return $rawData;
    }
    /**
     * 取得服務位置
     * @return array
     */
    public function getService()
    {
        return array(
            'service_name' => 'api',
            'cmd' => 'api/ewalletdisabler'
        );
    }
    /**
     * 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;
    }
}

$AgentEWalletDisabler = new AgentEWalletDisabler();
$AgentEWalletDisabler->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 AgentEWalletDisabler {
        /// <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() {
            AgentEWalletDisabler simulator = new AgentEWalletDisabler();
            //僅限走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.pfn =  "CREDITCARD";
            rawData.reason =  "系統自動取消";

            return rawData;
        }
        /// <summary>
        /// 取得服務位置
        /// </summary>
        private ServiceRequest GetService() {
            ServiceRequest rawData = new ServiceRequest();
            rawData.service_name = "api";
            rawData.cmd = "api/ewalletdisabler";
            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 AgentEWalletDisabler {
    /**
     * 經銷商商務代號
     */
    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) {
        AgentEWalletDisabler simulator = new AgentEWalletDisabler();
        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("pfn", "CREDITCARD");
        rawData.put("reason", "系統自動取消");

        return rawData;
    }
    /**
     * 取得服務位置
     * @return 串接服務資料
     */
    public Map getService() {
        Map<Object, Object> rawData = new HashMap<Object, Object>();
        rawData.put("service_name", "api");
        rawData.put("cmd", "api/ewalletdisabler");
        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');

/**
 * 經銷商串接-MYPAY電子錢包解除綁定
 */
function AgentEWalletDisabler() {
    // 經銷商商務代號
    this.agentUid = "518169081001";
    // 經銷商金鑰或認證碼
    this.agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
    // 特約商店商務代號
    this.storeUid = "289151880002";
    // 串接交易位置
    this.url = "https://pay.usecase.cc/api/agent";
};
/**
 * 取得串接欄位資料
 */
AgentEWalletDisabler.prototype.getRawData = function () {
    return {
        store_uid: this.storeUid,
        user_id: "phper",
        pfn: "CREDITCARD",
        reason: "系統自動取消",

    };
};
/**
 * 取得服務位置
 */
AgentEWalletDisabler.prototype.getService = function () {
    return {
        service_name: "api",
        cmd: "api/ewalletdisabler"
    };
};
/**
 * AES 256 加密
 */
AgentEWalletDisabler.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 到主機
 */
AgentEWalletDisabler.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();
    });
};
/**
 * 取得送出欄位資料
 */
AgentEWalletDisabler.prototype.getPostData = function () {
    return {
        "agent_uid": this.agentUid,
        "service": this.encrypt(this.getService(), this.agentKey),
        "encry_data": this.encrypt(this.getRawData(), this.agentKey)
    };
};
/**
 * 執行
 */
AgentEWalletDisabler.prototype.run = async function () {
    json = await this.post(this.getPostData())
    console.log(json);
};

AgentEWalletDisabler = new AgentEWalletDisabler();
AgentEWalletDisabler.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

"""經銷商串接-MYPAY電子錢包解除綁定
"""
class AgentEWalletDisabler:
    # 經銷商商務代號
    agentUid = "518169081001";
    # 經銷商金鑰或認證碼
    agentKey = b"0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
    # 特約商店商務代號
    storeUid = "289151880002"
    # 串接交易位置
    url = "https://pay.usecase.cc/api/agent"

    def getRawData(self):
        """取得串接欄位資料

        Returns:
            {dict}: 欄位資料
        """
        rawData = {
            'store_uid': self.storeUid,
            'user_id': "phper",
            'pfn': "CREDITCARD",
            'reason': "系統自動取消",
        }
        return rawData

    def getService(self):
        """取得服務位置

        Returns:
            {dict}: 服務位置資料
        """
        return {
            'service_name': 'api',
            'cmd': 'api/ewalletdisabler'
        }

    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)

AgentEWalletDisabler = AgentEWalletDisabler()
AgentEWalletDisabler.run()

回傳 JSON 結構如下:

{
    "code": "B200",
    "msg": "執行成功",
    "content": {
        "pfn": "CREDITCARD",
        "cardno": "400361******7729",
        "user_id": "phper",
        "cellphone_code": "886",
        "cellphone": "918123123",
        "virtual_pan": "b06419d0aaafb9683e163635a56bbadf",
        "enable": "0"
    }
}

透過API指定消費者帳號做解除電子錢包綁定

經銷商『MYPAY電子錢包解除綁定』參數說明

欄位 型態 說明
agent_uid string(16) 經銷商商務代號
service text {"service_name": "api", "cmd": "api\/ewalletdisabler"}
JSON格式,AES256加密資料
encry_data text 『MYPAY電子錢包解除綁定』欄位參考
JSON格式,AES256加密資料

『MYPAY電子錢包解除綁定』欄位

參數名稱 型態 說明 必須
store_uid string 特約商店商務代號 必填
user_id string 消費者帳號 必填
pfn string 綁定支付方式 必填
『付款方式』值參考
reason string 取消電子錢包綁定之原因 必填

『MYPAY電子錢包解除綁定』回傳欄位

參數名稱 型態 說明 必須
code string 交易回傳碼 『電子錢包執行狀態碼』值參考
msg string 回傳訊息
content null 交易網址 『電子錢包虛擬卡號回傳資訊』值參考

電子錢包虛擬卡號回傳資訊』回報欄位

參數名稱 型態 說明 必須
pfn string 支付類型
cardno string 綁定卡號 (僅顯示前六後四)
user_id string 消費者帳號
cellphone_code string 用以取消綁定之手機國碼
cellphone string 用以取消綁定之手機號碼
virtual_pan string 虛擬卡號
enable string 是否啟用 0.關閉 1.啟用

其他關聯欄位說明

關聯欄位

『商品項目』欄位

參數名稱 型態 說明 必須
id string 商品編號 必填
name string 商品名稱 必填
cost integer 商品單價 必填
amount integer 商品數量 必填
total integer 商品小計 必填

『MYPAY電子錢包資料』欄位

參數名稱 型態 說明 必須
virtualPan string 虛擬卡號 必填
userId string 電子錢包綁定帳號 必填
bizId string 電子錢包綁定商務代號 必填

『商品細項』欄位

參數名稱 型態 說明 必須
Description string 商品名稱 必填
Quantity string 數量 必填
UnitPrice string 單價 必填
Amount string 總金額 必填

值的定義

『付款方式』值內容

型態 說明 備註
CREDITCARD string 信用卡
ABROAD string 海外信用卡

『證號類型』值內容

型態 說明 備註
1 integer 身份證字號(預設)
2 integer 統一證號
3 integer 護照號碼

『電子發票是否開立狀態』值內容

型態 說明 備註
0 integer 不開立電子發票
1 integer 開立電子發票
2 integer 依系統設定(預設)

『電子發票稅率別』值內容

型態 說明 備註
1 integer 應稅(預設)
2 integer 零稅率
3 integer 免稅

『電子發票開立類型』值內容

型態 說明 備註
0 integer 未使用電子發票開立
1 integer 雲端發票
2 integer 發票捐贈
3 integer 實體發票 重要提示,若選擇此模式,商戶需要自行列印實體發票交付給消費者,系統不會寄送mail通知與中獎後也不會通知給消費者。電子發票列印格式,請參考國稅局頒布標準。

『雲端發票類型』值內容

型態 說明 備註
0 integer 未使用雲端發票類型
2 integer 手機條碼
3 integer 自然人憑證條碼
4 integer 以E-Mail寄送

『含不含簡訊費』值內容

型態 說明 備註
1 integer 含手續費
0 integer 不含手續費(預設)

『含不含手續費類型』值內容

型態 說明 備註
1 integer 含手續費
0 integer 不含手續費(預設)

『是否為經銷商代收費模式』值內容

型態 說明 備註
1 integer 是經銷商代收費模式
0 integer 不是經銷商代收費模式

『信用卡自動請款類型』值內容

型態 說明 備註
0 string 自行請款
1 string 自動請款(預設)

『信用卡別類型』值內容

型態 說明 備註
0 string 無法辨識或支付方式為非信用卡類
1 string VISA
2 string MasterCard
3 string JCB
4 string AMEX

『交易服務類型』值內容

型態 說明 備註
0 integer 尚未進行閘道交易
1 integer 代收代付
2 integer 特店模式

『回傳付款方式』值內容

型態 說明 備註
CREDITCARD string 信用卡
ABROAD string 海外信用卡

『閘道內容回傳格式類型』值內容

型態 說明 備註
0 integer 無法辨識
1 integer 網址
2 integer 超連結本文
3 integer xml
4 integer json
5 integer csv
6 integer 串流

『資料內容所屬支付名稱』值內容

型態 說明 備註
CREDITCARD string 信用卡
ABROAD string 海外信用卡

『電子發票開立狀態類型』值內容

型態 說明 備註
0 integer 不處理或已無效(預設)
1 integer 等候處理中
2 integer 發票開立成功
3 integer 發票開立失敗(系統或特約商店發票相關設定不正確)
4 integer 作癈
5 integer 發票開立失敗(系統發生錯誤)
6 integer 折讓

『電子發票紙本列印標題類型』值內容

型態 說明 備註
1 integer 文字
2 integer 圖形(圖片網址)

『電子發票列印類型』值內容

型態 說明 備註
0 integer 不列印 自行處置
1 integer 列印 電子發票 + 商品明細
2 integer 只印電子發票
3 integer 只印商品明細

『電子發票列印設備』值內容

型態 說明 備註
0 integer 自行處理
1 integer SUNMI V2 PRO

『電子錢包執行狀態碼』值內容

型態 說明 備註
100 string 資料不正確
400 string 系統錯誤
B200 string 執行成功
B500 string 執行失敗

『金流供應商代碼』值內容

型態 說明 備註
A1 string 裕富數位資融
A2 string 三環亞洲
B0 string 新光銀行
B1 string 永豐銀行
B2 string 合作金庫
B3 string 台北富邦
B4 string 玉山銀行
B5 string 台新銀行
B6 string 聯合信用卡處理中心
B7 string 台中商銀
B8 string 中國信託商業銀行
B9 string 上海商業儲蓄銀行
BA string 第一銀行
BB string 元大商業銀行
BC string 凱基銀行
BD string 國泰世華商業銀行
BE string 華泰商業銀行
S0 string 全網行銷股份有限公司(FamiPort)
S1 string 安源資訊股份有限公司(ibon)
S2 string 萊爾富國際股份有限公司(Hi-Life)
T0 string 高鉅科技
T1 string 藍新金流
W0 string 統振
W1 string 遊戲橘子數位
W2 string 台灣連線(LINEPay)
W3 string 博經
W4 string 街口電子支付
W5 string 悠遊卡
W6 string 一卡通票證
W7 string iCash
W8 string 全支付(PXPay plus)
W9 string 拍付國際資訊(Pi錢包)
E0 string MYTIX

『交易查詢』欄位

參數名稱 型態 說明 必須
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 實際交易幣別
voucher_paid array 有償票券項目 每筆『有償票券項目』欄位參考
voucher_free array 無償票券項目 每筆『無償票券項目』欄位參考
price string 請求交易點數/金額
actual_price string 實際交易點數/金額
recharge_code string 交易產品代碼
love_cost string 愛心捐款金額
retmsg string 回傳訊息
pfn string 付費方法
appropriation_date string 預計撥款日期(YYYYMMDD)
result_content_type string 資料內容所屬支付名稱 『資料內容所屬支付名稱』值參考
invoice_state integer 發票開立狀態 『電子發票開立狀態類型』值參考
invoice_date string 發票開立日期(YYYYMMDD)
invoice_wordtrack string 發票字軌
invoice_number string 發票號碼
invoice_rand_code string 電子發票隨機碼
invoice_seller_ban string 賣方統一編號
invoice_buyer_ban string 買方統一編號
invoice_left_qrcode string 電子發票左邊QrCode內容
invoice_middle_barcode string 電子發票中間Barcode內容(格式Code-39)
invoice_right_qrcode string 電子發票右邊QrCode內容
invoice_title_type integer 電子發票列印標題格式 『電子發票紙本列印標題類型』值參考
invoice_title string 電子發票列印標題格式
invoice_print_type integer 電子發票列印類型 『電子發票列印類型』值參考
invoice_print_device integer 電子發票列印設備 『電子發票列印設備』值參考
invoice_amount string 電子發票銷售總額
invoice_sales_amount string 電子發票銷售額
invoice_tax_amount string 電子發票稅額
invoice_order_detail string 電子發票全部產品明細(JSON格式) 『商品細項』值參考
invoice_ratetype integer 電子發票稅率別 『電子發票稅率別』值參考
invoice_input_type integer 電子發票開立類型 『電子發票開立類型』值參考
invoice_cloud_type string 電子發票開立類型-雲端發票類型 『雲端發票類型』值參考
invoice_mobile_code string 當invoice_cloud_type為2時紀錄的手機條碼
invoice_tax_id string 當invoice_cloud_type為2時紀錄的統一編號
invoice_natural_person string 當invoice_cloud_type為3時紀錄的自然人憑證條碼
invoice_m_post_zone string 當invoice_cloud_type為4時紀錄中獎時紙本發票郵遞區號
invoice_m_address string 當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時紀錄的發票地址
invoice_allowance array 電子發票折讓資訊 每筆『電子發票折讓資訊』欄位參考
echo_0 string 自訂回傳參數 1
echo_1 string 自訂回傳參數 2
echo_2 string 自訂回傳參數 3
echo_3 string 自訂回傳參數 4
echo_4 string 自訂回傳參數 5

附錄一:設定調整

附錄二:資料加密方式說明

  1. 所有的API送出HTTPs請求之欄位中,service 和 encry_data 欄位皆進行 AES256+BASE64 加密處理。
  2. AES加密,格式為CBC,長度為256bits,金鑰長度32,IV長度16,傳遞內文為加密後組合IV並經過Base64轉換後傳出。
  3. IV資料建議隨機產生。

附錄三:API模擬串接服務

提供模擬使用HTTP Protocol,透過POST方式傳遞資料到MYTIX, 並且得到回傳結果。

附錄四:測試區測試用信用卡卡號

下面卡號僅限在測試區測試使用

中國信託信用卡 (使用電子錢包功能適用)

Visa
一般交易 4003618704777729
有效日期 任意
安全碼 任意
3D交易密碼 1234567