經銷商API建立商戶技術文件
MYPAY為協助經銷商下的商店快速導入MYPAY支付工具進行收款,提供此「經銷商建立商店技術串接手冊」,讓經銷商可以透過API方式協助商店快速在MYPAY建立收款帳號。 經銷商可利用API傳送商店資料至MYPAY,MYPAY建立商店完成後,立即回覆經銷商,商店在MYPAY的特店代號,以利經銷商合作商店使用MYPAY金流支付工具收款。
安全性設計
所有的串接要求發動都僅能從經銷商的網頁伺服器發出請求,將傳輸的資料以AES256加密,再透過HTTPS加密傳輸。
資料驗證
串接參數中有一組由雜湊函式運算出的驗証碼,作為資料驗証用,以確保資料正確性。
系統架構
由經銷商的伺服器利用伺服端服務程式發動,以避免資料被竄改或攔截。為確保交易安全,MYPAY僅能接受 https connection。特別注意:系統僅接受使用TLS1.2以上通訊協定。
編修歷程
日期 | 版號 | 修訂內容 |
---|---|---|
111-12-27 | 1.0 | 原申請網址無法通知經銷商店家審核狀態, 故新增此功能『建立特約商店申請網址』 以利經銷商進行追蹤 |
MYPAY 資料傳遞格式
我們提供介接方式是透過https連線,只接受POST方式傳送串接資料。
(1)建立特約商店請求:經銷商發起建立特約商店之請求,審查完畢後,會主動回傳審查結果,若為審核通過,回傳內容中會包含特約商店的商務代號。
(2)建立特約商店申請網址請求:經銷商發起建立特約商店申請網址之請求,商務代號與申請代號無誤後,將回傳一組網址供特約商店進行線上申請,審查完畢後,會主動回傳審查結果,若為審核通過,回傳內容中會包含特約商店的唯一代碼。
介接網址
位置 | API介接網址 |
---|---|
測試區 | https://pay.usecase.cc/api/agent |
正式區 | https://mypay.tw/api/agent |
資料加密方式
AES 256編碼 + base64編碼(附錄四資料加密方式)
加密金鑰
金鑰會透過mail發送,也可從管理後台取得
文字編碼
一律使用UTF-8相容編碼
建立特約商店請求
<?php
/**
* 經銷商串接-特約商店申請
*/
final class AgentApplicant
{
/**
* 經銷商商務代號
* @var string
*/
public $agentUid = "A1234567891002";
/**
* 經銷商金鑰或認證碼
* @var string
*/
public $agentKey = "nq8KL8qNNCW12A3TBfAp4lU0y3PED8IQ";
/**
* 串接交易位置
* @var string
*/
public $url = "https://pay.usecase.cc/api/agent";
/**
* 取得串接欄位資料
* @return array
*/
public function getRawData()
{
$rawData = array();
$rawData['agent_uid'] = $this->agentUid;
$rawData['type'] = 0;
// 基本資料
$detail = [];
$detail['project_id'] = "1";
$detail['paymodes'] = [1, 9];
$detail['is_agent_einvoice'] = 1;
$detail['background_return_url'] = "https://query.usecase.cc/receive.php";
$detail['allot_bank_country'] = 1;
$detail['allot_bank_name'] = 23;
$detail['allot_bank_ext'] = 1872;
$detail['allot_bank_idname'] = "金城武";
$detail['allot_bank_id'] = "12330001144";
$detail['allot_bank_currency'] = "NTD";
$detail['service_mail'] = "[email protected]";
$detail['service_phone_type'] = 1;
$detail['service_phone_code'] = "886";
$detail['service_phone'] = "02-88888888";
// 範例用檔案
$sampleFile['size'] = 273;;
$sampleFile['type'] = "image/png";;
$sampleFile['data'] = "iVBORw0KGgoAAAANSUhEUgAAADMAAAASCAIAAAB5M3HuAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACmSURBVEhLY/hPe3Dv+1O/ey2LX+96//sTVIgIQD+XQRDx7qO3y4h338C4DILwu28gXQZBuNzHANRGa3To4wU012AiTPcxoKkYWITsvsHlMgiCuG8wugyCBqnLCh5NH3QuA7rpzOfrgyudwd0EAYOi1EBzEwQMcEkb/6Bvx/uTUHWoYMBcBnHT978/oYowwAC4jKCbIICuLiPSTRBAJ5eR5CYQ+P8fAPhjvViKbEtMAAAAAElFTkSuQmCC";
// 個人
$detail['zh_tw_name'] = "君の名は";
$detail['en_us_name'] = "Your Name";
$detail['applicant_name'] = "金城武";
$detail['applicant_id_type'] = 1;
$detail['applicant_id'] = "M123456789";
$detail['applicant_birthday'] = "20000131";
$detail['applicant_zip_code'] = '432';
$detail['applicant_address'] = "大肚里沙田路二段199號";
$detail['applicant_phone_code'] = "886";
$detail['applicant_phone'] = "04-26888888";
$detail['applicant_cellphone_code'] = '886';
$detail['applicant_cellphone'] = "0924-999999";
$detail['applicant_email'] = "[email protected]";
$detail['mcc_code'] = "1711";
$detail['real_zip_code'] = "407";
$detail['real_address'] = "市政北二路236號26樓之1";
$principal_id_front_img['name'] = "身分證正面.png";
$principal_id_front_img['size'] = $sampleFile['size'];
$principal_id_front_img['type'] = $sampleFile['type'];
$principal_id_front_img['data'] = $sampleFile['data'];
$principal_id_obverse_img['name'] = "身分證反面.png";
$principal_id_obverse_img['size'] = $sampleFile['size'];
$principal_id_obverse_img['type'] = $sampleFile['type'];
$principal_id_obverse_img['data'] = $sampleFile['data'];
$principal_driverlicense_healthidcard_img['name'] = "申請人第二證件.png";
$principal_driverlicense_healthidcard_img['size'] = $sampleFile['size'];
$principal_driverlicense_healthidcard_img['type'] = $sampleFile['type'];
$principal_driverlicense_healthidcard_img['data'] = $sampleFile['data'];
$business_photos_img_1 = $sampleFile;
$business_photos_img_1['name'] = "營業照片第一張.png";
$business_photos_img_2 = $sampleFile;
$business_photos_img_2['name'] = "營業照片第二張.png";
$business_photos_img_3 = $sampleFile;
$business_photos_img_3['name'] = "營業照片第三張.png";
$business_photos_img_4 = $sampleFile;
$business_photos_img_4['name'] = "營業照片第四張.png";
$business_photos_4_img[] = $business_photos_img_1;
$business_photos_4_img[] = $business_photos_img_2;
$business_photos_4_img[] = $business_photos_img_3;
$business_photos_4_img[] = $business_photos_img_4;
$bank_passbook_img['name'] = '銀行存摺封面影本.png';
$bank_passbook_img['size'] = $sampleFile['size'];
$bank_passbook_img['type'] = $sampleFile['type'];
$bank_passbook_img['data'] = $sampleFile['data'];
$detail['files'] = ['principal_id_front_img' => $principal_id_front_img,
'principal_id_obverse_img' => $principal_id_obverse_img,
'principal_driverlicense_healthidcard_img' => $principal_driverlicense_healthidcard_img,
'business_photos_4_img' => $business_photos_4_img,
'bank_passbook_img' => $bank_passbook_img];
/*
// 公司
$detail['org_type_uid'] = 2;
$detail['tong_bian'] = "28915188";
$detail['id_name'] = "高鉅科技股份有限公司";
$detail['setup_date'] = "20081001";
$detail['mcc_code'] = "1711";
$detail['capital_currency'] = "NTD";
$detail['capital'] = 50000000;
$detail['zh_tw_name'] = "MYPAY-小野喵";
$detail['en_us_name'] = "MYPAY - Cat";
$detail['zip_code'] = "407";
$detail['address'] = "市政北二路236號26樓之1";
$detail['real_zip_code'] = "407";
$detail['real_address'] = "市政北二路236號26樓之1";
$detail['envoice_zip_code'] = "407";
$detail['envoice_address'] = "市政北二路236號26樓之1";
$detail['principal_name'] = "金城武";
$detail['principal_id_type'] = 1;
$detail['principal_id'] = "M123456789";
$detail['principal_birthday'] = "20000101";
$detail['principal_phone_code'] = "886";
$detail['principal_phone'] = "04-26888888";
$detail['principal_cellphone_code'] = '886';
$detail['principal_cellphone'] = "0924-999999";
$detail['principal_zip_code'] = "407";
$detail['principal_address'] = "市政北二路236號26樓之1";
$detail['principal_email'] = "[email protected]";
$detail['salesman_name'] = "金城武";
$detail['salesman_phone_code'] = "886";
$detail['salesman_phone'] = "02-8888888";
$detail['salesman_cellphone_code'] = "886";
$detail['salesman_cellphone'] = "0920-999999";
$detail['salesman_mail'] = "[email protected]";
$detail['accountant_name'] = "金城武";
$detail['accountant_phone_code'] = "886";
$detail['accountant_phone'] = "02-8888888";
$detail['accountant_fax_code'] = "886";
$detail['accountant_fax'] = "02-8888887";
$detail['accountant_cellphone_code'] = "886";
$detail['accountant_cellphone'] = "0920-999999";
$detail['accountant_mail'] = "[email protected]";
$detail['technician_name'] = "金城武";
$detail['technician_phone_code'] = "886";
$detail['technician_phone'] = "02-8888888";
$detail['technician_cellphone_code'] = "886";
$detail['technician_cellphone'] = "0920-999999";
$detail['technician_mail'] = "[email protected]";
$principal_id_front_img['name'] = "身分證正面.png";
$principal_id_front_img['size'] = $sampleFile['size'];
$principal_id_front_img['type'] = $sampleFile['type'];
$principal_id_front_img['data'] = $sampleFile['data'];
$principal_id_obverse_img['name'] = "身分證反面.png";
$principal_id_obverse_img['size'] = $sampleFile['size'];
$principal_id_obverse_img['type'] = $sampleFile['type'];
$principal_id_obverse_img['data'] = $sampleFile['data'];
$principal_driverlicense_healthidcard_img['name'] = "負責人第二證件.png";
$principal_driverlicense_healthidcard_img['size'] = $sampleFile['size'];
$principal_driverlicense_healthidcard_img['type'] = $sampleFile['type'];
$principal_driverlicense_healthidcard_img['data'] = $sampleFile['data'];
$approvalletter_img['name'] = "變更事項登記表.png";
$approvalletter_img['size'] = $sampleFile['size'];
$approvalletter_img['type'] = $sampleFile['type'];
$approvalletter_img['data'] = $sampleFile['data'];
$report_401_405_img = $sampleFile;
$report_401_405_img['name'] = "401報表-108-1.png";
$business_photos_img_1 = $sampleFile;
$business_photos_img_1['name'] = "營業照片第一張.png";
$business_photos_img_2 = $sampleFile;
$business_photos_img_2['name'] = "營業照片第二張.png";
$business_photos_img_3 = $sampleFile;
$business_photos_img_3['name'] = "營業照片第三張.png";
$business_photos_img_4 = $sampleFile;
$business_photos_img_4['name'] = "營業照片第四張.png";
$business_photos_4_img[] = $business_photos_img_1;
$business_photos_4_img[] = $business_photos_img_2;
$business_photos_4_img[] = $business_photos_img_3;
$business_photos_4_img[] = $business_photos_img_4;
$bank_passbook_img['name'] = '銀行存摺封面影本.png';
$bank_passbook_img['size'] = $sampleFile['size'];
$bank_passbook_img['type'] = $sampleFile['type'];
$bank_passbook_img['data'] = $sampleFile['data'];
$detail['files'] = ['principal_id_front_img' => $principal_id_front_img,
'principal_id_obverse_img' => $principal_id_obverse_img,
'principal_driverlicense_healthidcard_img' => $principal_driverlicense_healthidcard_img,
'approvalletter_img' => $approvalletter_img,
'report_401_405_img' => $report_401_405_img,
'business_photos_4_img' => $business_photos_4_img,
'bank_passbook_img' => $bank_passbook_img];
*/
$rawData['detail'] = $detail;
return $rawData;
}
/**
* 取得服務位置
* @return array
*/
public function getService()
{
return array(
'service_name' => 'store',
'cmd' => 'api/authorizedstore'
);
}
/**
* 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, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $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;
}
}
$AgentApplicant = new AgentApplicant();
$AgentApplicant->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 AgentApplicant {
/// <summary>
/// 經銷商商務代號
/// </summary>
public string agentUid = "A1234567891002";
/// <summary>
/// 經銷商金鑰或認證碼
/// </summary>
public string agentKey = "nq8KL8qNNCW12A3TBfAp4lU0y3PED8IQ";
/// <summary>
/// 串接交易位置
/// </summary>
public string url = "https://pay.usecase.cc/api/agent";
/// <summary>
/// 執行
/// </summary>
static void Main() {
AgentApplicant simulator = new AgentApplicant();
//僅限走https的Tls 1.2以上版本
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//發送至遠端
var result = simulator.Post(simulator.GetPostData());
System.Console.WriteLine(result);
}
/// <summary>
/// 取得串接欄位資料
/// </summary>
private DataRequest GetRawData() {
// 範例用檔案
DataFile sampleFile = new DataFile();
sampleFile.size = 273;;
sampleFile.type = "image/png";;
sampleFile.data = "iVBORw0KGgoAAAANSUhEUgAAADMAAAASCAIAAAB5M3HuAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACmSURBVEhLY/hPe3Dv+1O/ey2LX+96//sTVIgIQD+XQRDx7qO3y4h338C4DILwu28gXQZBuNzHANRGa3To4wU012AiTPcxoKkYWITsvsHlMgiCuG8wugyCBqnLCh5NH3QuA7rpzOfrgyudwd0EAYOi1EBzEwQMcEkb/6Bvx/uTUHWoYMBcBnHT978/oYowwAC4jKCbIICuLiPSTRBAJ5eR5CYQ+P8fAPhjvViKbEtMAAAAAElFTkSuQmCC";
// 基本資料
dynamic detail = new ExpandoObject();
detail.project_id = "1";
ArrayList paymodes = new ArrayList();
paymodes.Add(1);
paymodes.Add(9);
detail.paymodes = paymodes;
detail.is_agent_einvoice = 1;
detail.background_return_url = "https://query.usecase.cc/receive.php";
detail.allot_bank_country = 1;
detail.allot_bank_name = 23;
detail.allot_bank_ext = 1872;
detail.allot_bank_idname = "金城武";
detail.allot_bank_id = "12330001144";
detail.allot_bank_currency = "NTD";
detail.service_mail = "[email protected]";
detail.service_phone_type = 1;
detail.service_phone_code = "886";
detail.service_phone = "02-88888888";
// 個人
detail.zh_tw_name = "君の名は";
detail.en_us_name = "Your Name";
detail.applicant_name = "金城武";
detail.applicant_id_type = 1;
detail.applicant_id = "M123456789";
detail.applicant_birthday = "20000131";
detail.applicant_zip_code = "432";
detail.applicant_address = "大肚里沙田路二段199號";
detail.applicant_phone_code = "886";
detail.applicant_phone = "04-26888888";
detail.applicant_cellphone_code = "886";
detail.applicant_cellphone = "0924-999999";
detail.applicant_email = "[email protected]";
detail.mcc_code = "1711";
detail.real_zip_code = "407";
detail.real_address = "市政北二路236號26樓之1";
DataFile principal_id_front_img = new DataFile();
principal_id_front_img.name = "身分證正面.png";
principal_id_front_img.size = sampleFile.size;
principal_id_front_img.type = sampleFile.type;
principal_id_front_img.data = sampleFile.data;
DataFile principal_id_obverse_img = new DataFile();
principal_id_obverse_img.name = "身分證反面.png";
principal_id_obverse_img.size = sampleFile.size;
principal_id_obverse_img.type = sampleFile.type;
principal_id_obverse_img.data = sampleFile.data;
DataFile principal_driverlicense_healthidcard_img = new DataFile();
principal_driverlicense_healthidcard_img.name = "申請人第二證件.png";
principal_driverlicense_healthidcard_img.size = sampleFile.size;
principal_driverlicense_healthidcard_img.type = sampleFile.type;
principal_driverlicense_healthidcard_img.data = sampleFile.data;
ArrayList business_photos_4_img = new ArrayList();
DataFile business_photos_img_1 = new DataFile();
business_photos_img_1.name = "營業照片第一張.png";
business_photos_img_1.size = sampleFile.size;
business_photos_img_1.type = sampleFile.type;
business_photos_img_1.data = sampleFile.data;
business_photos_4_img.Add(business_photos_img_1);
DataFile business_photos_img_2 = new DataFile();
business_photos_img_2.name = "營業照片第一張.png";
business_photos_img_2.size = sampleFile.size;
business_photos_img_2.type = sampleFile.type;
business_photos_img_2.data = sampleFile.data;
business_photos_4_img.Add(business_photos_img_2);
DataFile business_photos_img_3 = new DataFile();
business_photos_img_3.name = "營業照片第一張.png";
business_photos_img_3.size = sampleFile.size;
business_photos_img_3.type = sampleFile.type;
business_photos_img_3.data = sampleFile.data;
business_photos_4_img.Add(business_photos_img_3);
DataFile business_photos_img_4 = new DataFile();
business_photos_img_4.name = "營業照片第一張.png";
business_photos_img_4.size = sampleFile.size;
business_photos_img_4.type = sampleFile.type;
business_photos_img_4.data = sampleFile.data;
business_photos_4_img.Add(business_photos_img_4);
DataFile bank_passbook_img = new DataFile();
bank_passbook_img.name = "銀行存摺封面影本.png";
bank_passbook_img.size = sampleFile.size;
bank_passbook_img.type = sampleFile.type;
bank_passbook_img.data = sampleFile.data;
dynamic files = new ExpandoObject();
files.principal_id_front_img = principal_id_front_img;
files.principal_id_obverse_img = principal_id_obverse_img;
files.principal_driverlicense_healthidcard_img = principal_driverlicense_healthidcard_img;
files.business_photos_4_img = business_photos_4_img;
files.bank_passbook_img = bank_passbook_img;
detail.files = files;
/*
// 公司
detail.org_type_uid = 2;
detail.tong_bian = "28915188";
detail.id_name = "高鉅科技股份有限公司";
detail.setup_date = "20081001";
detail.mcc_code = "1711";
detail.capital_currency = "NTD";
detail.capital = 50000000;
detail.zh_tw_name = "MYPAY-小野喵";
detail.en_us_name = "MYPAY - Cat";
detail.zip_code = "407";
detail.address = "市政北二路236號26樓之1";
detail.real_zip_code = "407";
detail.real_address = "市政北二路236號26樓之1";
detail.envoice_zip_code = "407";
detail.envoice_address = "市政北二路236號26樓之1";
detail.principal_name = "金城武";
detail.principal_id_type = 1;
detail.principal_id = "M123456789";
detail.principal_birthday = "20000101";
detail.principal_phone_code = "886";
detail.principal_phone = "04-26888888";
detail.principal_cellphone_code = "886";
detail.principal_cellphone = "0924-999999";
detail.principal_zip_code = "407";
detail.principal_address = "市政北二路236號26樓之1";
detail.principal_email = "[email protected]";
detail.salesman_name = "金城武";
detail.salesman_phone_code = "886";
detail.salesman_phone = "02-8888888";
detail.salesman_cellphone_code = "886";
detail.salesman_cellphone = "0920-999999";
detail.salesman_mail = "[email protected]";
detail.accountant_name = "金城武";
detail.accountant_phone_code = "886";
detail.accountant_phone = "02-8888888";
detail.accountant_fax_code = "886";
detail.accountant_fax = "02-8888887";
detail.accountant_cellphone_code = "886";
detail.accountant_cellphone = "0920-999999";
detail.accountant_mail = "[email protected]";
detail.technician_name = "金城武";
detail.technician_phone_code = "886";
detail.technician_phone = "02-8888888";
detail.technician_cellphone_code = "886";
detail.technician_cellphone = "0920-999999";
detail.technician_mail = "[email protected]";
File principal_id_front_img = new File();
principal_id_front_img.name = "身分證正面.png";
principal_id_front_img.size = sampleFile.size;
principal_id_front_img.type = sampleFile.type;
principal_id_front_img.data = sampleFile.data;
File principal_id_obverse_img = new File();
principal_id_obverse_img.name = "身分證反面.png";
principal_id_obverse_img.size = sampleFile.size;
principal_id_obverse_img.type = sampleFile.type;
principal_id_obverse_img.data = sampleFile.data;
File principal_driverlicense_healthidcard_img = new File();
principal_driverlicense_healthidcard_img.name = "申請人第二證件.png";
principal_driverlicense_healthidcard_img.size = sampleFile.size;
principal_driverlicense_healthidcard_img.type = sampleFile.type;
principal_driverlicense_healthidcard_img.data = sampleFile.data;
File approvalletter_img = new File();
approvalletter_img.name = "變更事項登記表.png";
approvalletter_img.size = sampleFile.size;
approvalletter_img.type = sampleFile.type;
approvalletter_img.data = sampleFile.data;
File report_401_405_img = new File();
report_401_405_img.name = "401報表-108-1.png";
report_401_405_img.size = sampleFile.size;
report_401_405_img.type = sampleFile.type;
report_401_405_img.data = sampleFile.data;
ArrayList business_photos_4_img = new ArrayList();
File business_photos_img_1 = new File();
business_photos_img_1.name = "營業照片第一張.png";
business_photos_img_1.size = sampleFile.size;
business_photos_img_1.type = sampleFile.type;
business_photos_img_1.data = sampleFile.data;
business_photos_4_img.Add(business_photos_img_1);
File business_photos_img_2 = new File();
business_photos_img_2.name = "營業照片第一張.png";
business_photos_img_2.size = sampleFile.size;
business_photos_img_2.type = sampleFile.type;
business_photos_img_2.data = sampleFile.data;
business_photos_4_img.Add(business_photos_img_2);
File business_photos_img_3 = new File();
business_photos_img_3.name = "營業照片第一張.png";
business_photos_img_3.size = sampleFile.size;
business_photos_img_3.type = sampleFile.type;
business_photos_img_3.data = sampleFile.data;
business_photos_4_img.Add(business_photos_img_3);
File business_photos_img_4 = new File();
business_photos_img_4.name = "營業照片第一張.png";
business_photos_img_4.size = sampleFile.size;
business_photos_img_4.type = sampleFile.type;
business_photos_img_4.data = sampleFile.data;
business_photos_4_img.Add(business_photos_img_4);
File bank_passbook_img = new File();
bank_passbook_img.name = "銀行存摺封面影本.png";
bank_passbook_img.size = sampleFile.size;
bank_passbook_img.type = sampleFile.type;
bank_passbook_img.data = sampleFile.data;
dynamic files = new ExpandoObject();
files.principal_id_front_img = principal_id_front_img;
files.principal_id_obverse_img = principal_id_obverse_img;
files.principal_driverlicense_healthidcard_img = principal_driverlicense_healthidcard_img;
files.approvalletter_img = approvalletter_img;
files.report_401_405_img = report_401_405_img;
files.business_photos_4_img = business_photos_4_img;
files.bank_passbook_img = bank_passbook_img;
detail.files = files;
*/
DataRequest rawData = new DataRequest();
rawData.agent_uid = this.agentUid;
rawData.type = 0;
rawData.detail = detail;
return rawData;
}
/// <summary>
/// 取得服務位置
/// </summary>
private ServiceRequest GetService() {
ServiceRequest rawData = new ServiceRequest();
rawData.service_name = "store";
rawData.cmd = "api/authorizedstore";
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 DataRequest {
public string agent_uid { get; set; }
public int type { get; set; }
public ExpandoObject detail { get; set; }
}
/// <summary>
/// 夾檔檔案資訊
/// </summary>
public class DataFile {
public string name { get; set; }
public int size { get; set; }
public string type { get; set; }
public string data { get; set; }
}
/// <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 AgentApplicant {
/**
* 經銷商商務代號
*/
String agentUid = "A1234567891002";
/**
* 經銷商金鑰或認證碼
*/
String agentKey = "nq8KL8qNNCW12A3TBfAp4lU0y3PED8IQ";
/**
* 串接交易位置
*/
String url = "https://pay.usecase.cc/api/agent";
/**
* 執行
* @param args
*/
public static void main(String[] args) {
AgentApplicant simulator = new AgentApplicant();
String json = simulator.post(simulator.getPostData());
System.out.print(json);
}
@SuppressWarnings(value = { "unchecked", "deprecation" })
/**
* 取得串接欄位資料
* @return 串接原始資料
*/
public Map getRawData() {
// 範例用檔案
Map<Object, Object> sampleFile = new HashMap<Object, Object>();
sampleFile.put("size", 273);
sampleFile.put("type", "image/png");
sampleFile.put("data", "iVBORw0KGgoAAAANSUhEUgAAADMAAAASCAIAAAB5M3HuAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACmSURBVEhLY/hPe3Dv+1O/ey2LX+96//sTVIgIQD+XQRDx7qO3y4h338C4DILwu28gXQZBuNzHANRGa3To4wU012AiTPcxoKkYWITsvsHlMgiCuG8wugyCBqnLCh5NH3QuA7rpzOfrgyudwd0EAYOi1EBzEwQMcEkb/6Bvx/uTUHWoYMBcBnHT978/oYowwAC4jKCbIICuLiPSTRBAJ5eR5CYQ+P8fAPhjvViKbEtMAAAAAElFTkSuQmCC");
// 基本資料
Map<Object, Object> detail = new HashMap<Object, Object>();
detail.put("project_id", "1");
ArrayList paymodes = new ArrayList();
paymodes.add(1);
paymodes.add(9);
detail.put("paymodes", paymodes);
detail.put("is_agent_einvoice", 1);
detail.put("background_return_url", "https://query.usecase.cc/receive.php");
detail.put("allot_bank_country", 1);
detail.put("allot_bank_name", 23);
detail.put("allot_bank_ext", 1872);
detail.put("allot_bank_idname", "金城武");
detail.put("allot_bank_id", "12330001144");
detail.put("allot_bank_currency", "NTD");
detail.put("service_mail", "[email protected]");
detail.put("service_phone_type", 1);
detail.put("service_phone_code", "886");
detail.put("service_phone", "02-88888888");
// 個人
detail.put("zh_tw_name", "君の名は");
detail.put("en_us_name", "Your Name");
detail.put("applicant_name", "金城武");
detail.put("applicant_id_type", 1);
detail.put("applicant_id", "M123456789");
detail.put("applicant_birthday", "20000131");
detail.put("applicant_zip_code", "432");
detail.put("applicant_address", "大肚里沙田路二段199號");
detail.put("applicant_phone_code", "886");
detail.put("applicant_phone", "04-26888888");
detail.put("applicant_cellphone_code", "886");
detail.put("applicant_cellphone", "0924-999999");
detail.put("applicant_email", "[email protected]");
detail.put("mcc_code", "1711");
detail.put("real_zip_code", "407");
detail.put("real_address", "市政北二路236號26樓之1");
Map<Object, Object> principal_id_front_img = new HashMap<Object, Object>();
principal_id_front_img.put("name", "身分證正面.png");
principal_id_front_img.put("size", sampleFile.get("size"));
principal_id_front_img.put("type", sampleFile.get("type"));
principal_id_front_img.put("data", sampleFile.get("data"));
Map<Object, Object> principal_id_obverse_img = new HashMap<Object, Object>();
principal_id_obverse_img.put("name", "身分證反面.png");
principal_id_obverse_img.put("size", sampleFile.get("size"));
principal_id_obverse_img.put("type", sampleFile.get("type"));
principal_id_obverse_img.put("data", sampleFile.get("data"));
Map<Object, Object> principal_driverlicense_healthidcard_img = new HashMap<Object, Object>();
principal_driverlicense_healthidcard_img.put("name", "申請人第二證件.png");
principal_driverlicense_healthidcard_img.put("size", sampleFile.get("size"));
principal_driverlicense_healthidcard_img.put("type", sampleFile.get("type"));
principal_driverlicense_healthidcard_img.put("data", sampleFile.get("data"));
ArrayList business_photos_4_img = new ArrayList();
Map<Object, Object> business_photos_4_img_1 = new HashMap<Object, Object>();
business_photos_4_img_1.put("name", "營業照片第一張.png");
business_photos_4_img_1.put("size", sampleFile.get("size"));
business_photos_4_img_1.put("type", sampleFile.get("type"));
business_photos_4_img_1.put("data", sampleFile.get("data"));
business_photos_4_img.add(business_photos_4_img_1);
Map<Object, Object> business_photos_4_img_2 = new HashMap<Object, Object>();
business_photos_4_img_2.put("name", "營業照片第二張.png");
business_photos_4_img_2.put("size", sampleFile.get("size"));
business_photos_4_img_2.put("type", sampleFile.get("type"));
business_photos_4_img_2.put("data", sampleFile.get("data"));
business_photos_4_img.add(business_photos_4_img_2);
Map<Object, Object> business_photos_4_img_3 = new HashMap<Object, Object>();
business_photos_4_img_3.put("name", "營業照片第三張.png");
business_photos_4_img_3.put("size", sampleFile.get("size"));
business_photos_4_img_3.put("type", sampleFile.get("type"));
business_photos_4_img_3.put("data", sampleFile.get("data"));
business_photos_4_img.add(business_photos_4_img_3);
Map<Object, Object> business_photos_4_img_4 = new HashMap<Object, Object>();
business_photos_4_img_4.put("name", "營業照片第四張.png");
business_photos_4_img_4.put("size", sampleFile.get("size"));
business_photos_4_img_4.put("type", sampleFile.get("type"));
business_photos_4_img_4.put("data", sampleFile.get("data"));
business_photos_4_img.add(business_photos_4_img_4);
Map<Object, Object> bank_passbook_img = new HashMap<Object, Object>();
bank_passbook_img.put("name", "銀行存摺封面影本.png");
bank_passbook_img.put("size", sampleFile.get("size"));
bank_passbook_img.put("type", sampleFile.get("type"));
bank_passbook_img.put("data", sampleFile.get("data"));
Map<Object, Object> files = new HashMap<Object, Object>();
files.put("principal_id_front_img", principal_id_front_img);
files.put("principal_id_obverse_img", principal_id_obverse_img);
files.put("principal_driverlicense_healthidcard_img", principal_driverlicense_healthidcard_img);
files.put("business_photos_4_img", business_photos_4_img);
files.put("bank_passbook_img", bank_passbook_img);
detail.put("files", files);
/*
// 公司
detail.put("org_type_uid", 2);
detail.put("tong_bian", "28915188");
detail.put("id_name", "高鉅科技股份有限公司");
detail.put("setup_date", "20081001");
detail.put("mcc_code", "1711");
detail.put("capital_currency", "NTD");
detail.put("capital", 50000000);
detail.put("zh_tw_name", "MYPAY-小野喵");
detail.put("en_us_name", "MYPAY - Cat");
detail.put("zip_code", "407");
detail.put("address", "市政北二路236號26樓之1");
detail.put("real_zip_code", "407");
detail.put("real_address", "市政北二路236號26樓之1");
detail.put("envoice_zip_code", "407");
detail.put("envoice_address", "市政北二路236號26樓之1");
detail.put("principal_name", "金城武");
detail.put("principal_id_type", 1);
detail.put("principal_id", "M123456789");
detail.put("principal_birthday", "20000101");
detail.put("principal_phone_code", "886");
detail.put("principal_phone", "04-26888888");
detail.put("principal_cellphone_code", "886");
detail.put("principal_cellphone", "0924-999999");
detail.put("principal_zip_code", "407");
detail.put("principal_address", "市政北二路236號26樓之1");
detail.put("principal_email", "[email protected]");
detail.put("salesman_name", "金城武");
detail.put("salesman_phone_code", "886");
detail.put("salesman_phone", "02-8888888");
detail.put("salesman_cellphone_code", "886");
detail.put("salesman_cellphone", "0920-999999");
detail.put("salesman_mail", "[email protected]");
detail.put("accountant_name", "金城武");
detail.put("accountant_phone_code", "886");
detail.put("accountant_phone", "02-8888888");
detail.put("accountant_fax_code", "886");
detail.put("accountant_fax", "02-8888887");
detail.put("accountant_cellphone_code", "886");
detail.put("accountant_cellphone", "0920-999999");
detail.put("accountant_mail", "[email protected]");
detail.put("technician_name", "金城武");
detail.put("technician_phone_code", "886");
detail.put("technician_phone", "02-8888888");
detail.put("technician_cellphone_code", "886");
detail.put("technician_cellphone", "0920-999999");
detail.put("technician_mail", "[email protected]");
Map<Object, Object> principal_id_front_img = new HashMap<Object, Object>();
principal_id_front_img.put("name", "身分證正面.png");
principal_id_front_img.put("size", sampleFile.get("size"));
principal_id_front_img.put("type", sampleFile.get("type"));
principal_id_front_img.put("data", sampleFile.get("data"));
Map<Object, Object> principal_id_obverse_img = new HashMap<Object, Object>();
principal_id_obverse_img.put("name", "身分證反面.png");
principal_id_obverse_img.put("size", sampleFile.get("size"));
principal_id_obverse_img.put("type", sampleFile.get("type"));
principal_id_obverse_img.put("data", sampleFile.get("data"));
Map<Object, Object> principal_driverlicense_healthidcard_img = new HashMap<Object, Object>();
principal_driverlicense_healthidcard_img.put("name", "申請人第二證件.png");
principal_driverlicense_healthidcard_img.put("size", sampleFile.get("size"));
principal_driverlicense_healthidcard_img.put("type", sampleFile.get("type"));
principal_driverlicense_healthidcard_img.put("data", sampleFile.get("data"));
Map<Object, Object> approvalletter_img = new HashMap<Object, Object>();
approvalletter_img.put("name", "變更事項登記表.png");
approvalletter_img.put("size", sampleFile.get("size"));
approvalletter_img.put("type", sampleFile.get("type"));
approvalletter_img.put("data", sampleFile.get("data"));
Map<Object, Object> report_401_405_img = new HashMap<Object, Object>();
report_401_405_img.put("name", "401報表-108-1.png");
report_401_405_img.put("size", sampleFile.get("size"));
report_401_405_img.put("type", sampleFile.get("type"));
report_401_405_img.put("data", sampleFile.get("data"));
ArrayList business_photos_4_img = new ArrayList();
Map<Object, Object> business_photos_4_img_1 = new HashMap<Object, Object>();
business_photos_4_img_1.put("name", "營業照片第一張.png");
business_photos_4_img_1.put("size", sampleFile.get("size"));
business_photos_4_img_1.put("type", sampleFile.get("type"));
business_photos_4_img_1.put("data", sampleFile.get("data"));
business_photos_4_img.add(business_photos_4_img_1);
Map<Object, Object> business_photos_4_img_2 = new HashMap<Object, Object>();
business_photos_4_img_2.put("name", "營業照片第二張.png");
business_photos_4_img_2.put("size", sampleFile.get("size"));
business_photos_4_img_2.put("type", sampleFile.get("type"));
business_photos_4_img_2.put("data", sampleFile.get("data"));
business_photos_4_img.add(business_photos_4_img_2);
Map<Object, Object> business_photos_4_img_3 = new HashMap<Object, Object>();
business_photos_4_img_3.put("name", "營業照片第三張.png");
business_photos_4_img_3.put("size", sampleFile.get("size"));
business_photos_4_img_3.put("type", sampleFile.get("type"));
business_photos_4_img_3.put("data", sampleFile.get("data"));
business_photos_4_img.add(business_photos_4_img_3);
Map<Object, Object> business_photos_4_img_4 = new HashMap<Object, Object>();
business_photos_4_img_4.put("name", "營業照片第四張.png");
business_photos_4_img_4.put("size", sampleFile.get("size"));
business_photos_4_img_4.put("type", sampleFile.get("type"));
business_photos_4_img_4.put("data", sampleFile.get("data"));
business_photos_4_img.add(business_photos_4_img_4);
Map<Object, Object> bank_passbook_img = new HashMap<Object, Object>();
bank_passbook_img.put("name", "銀行存摺封面影本.png");
bank_passbook_img.put("size", sampleFile.get("size"));
bank_passbook_img.put("type", sampleFile.get("type"));
bank_passbook_img.put("data", sampleFile.get("data"));
Map<Object, Object> files = new HashMap<Object, Object>();
files.put("principal_id_front_img", principal_id_front_img);
files.put("principal_id_obverse_img", principal_id_obverse_img);
files.put("principal_driverlicense_healthidcard_img", principal_driverlicense_healthidcard_img);
files.put("approvalletter_img", approvalletter_img);
files.put("report_401_405_img", report_401_405_img);
files.put("business_photos_4_img", business_photos_4_img);
files.put("bank_passbook_img", bank_passbook_img);
detail.put("files", files);
*/
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("agent_uid", this.agentUid);
rawData.put("type", 0);
rawData.put("detail", detail);
return rawData;
}
/**
* 取得服務位置
* @return 串接服務資料
*/
public Map getService() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("service_name", "store");
rawData.put("cmd", "api/authorizedstore");
return rawData;
}
/**
* AES 256 加密
* @param rawData 原始資料
* @param AesKey AES256金鑰字串
* @return 轉換成Base64資料
*/
public String encrypt(Map rawData, String AesKey) {
try {
ObjectMapper objMapper = new ObjectMapper();
byte[] data = objMapper.writeValueAsString(rawData).getBytes(UTF_8);
byte[] key = AesKey.getBytes(UTF_8);
// 16 bytes is the IV size for AES256
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
// Random iv
SecureRandom rng = new SecureRandom();
byte[] ivBytes = new byte[16];
rng.nextBytes(ivBytes);
cipher.init(true, new ParametersWithIV(new KeyParameter(key),
ivBytes));
byte[] outBuf = new byte[cipher.getOutputSize(data.length)];
int processed = cipher
.processBytes(data, 0, data.length, outBuf, 0);
processed += cipher.doFinal(outBuf, processed);
byte[] outBuf2 = new byte[processed + 16]; // Make room for iv
System.arraycopy(ivBytes, 0, outBuf2, 0, 16); // Add iv
System.arraycopy(outBuf, 0, outBuf2, 16, processed);
Base64.Encoder encoder = Base64.getEncoder();
String base64 = encoder.encodeToString(outBuf2);
return base64;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 資料 POST 到主機
* @param qstr 串接資料
* @return 服務回傳JSON資訊
*/
public String post(String qstr) {
String result = "";
try {
// 資料
byte[] qstr_bytes = qstr.getBytes(StandardCharsets.UTF_8);
URL iurl = new URL(this.url);
SSLContext sc = SSLContext.getInstance("TLSv1.2"); // $NON-NLS-1$
sc.init(null, null, new java.security.SecureRandom());
HttpsURLConnection con = (HttpsURLConnection) iurl.openConnection();
con.setSSLSocketFactory(sc.getSocketFactory());
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
con.setRequestProperty("Content-Length",
String.valueOf(qstr_bytes.length));
con.setRequestProperty("Accept-Charset", "UTF-8");
con.setDoOutput(true);
con.setDoInput(true);
con.getOutputStream()
.write(qstr.getBytes(Charset.forName("UTF-8")));
con.getOutputStream().flush();
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream(), "UTF-8"));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine + "\r\n");
}
try {
result = response.toString();
} finally {
in.close();
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return result;
}
/**
* 取得送出欄位資料
* @return POST完整資料
*/
public String getPostData() {
String postData = "";
try {
// Base64需要使用UrlEncode做傳輸
String data_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getRawData(), this.agentKey), "UTF-8");
String svr_toUrlEncode = URLEncoder.encode(
this.encrypt(this.getService(), this.agentKey), "UTF-8");
postData = "agent_uid=" + this.agentUid + "&service="
+ svr_toUrlEncode + "&encry_data=" + data_toUrlEncode;
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return postData;
}
}
const crypto = require('crypto');
const httpRequest = require('https');
/**
* 經銷商串接-特約商店申請
*/
function AgentApplicant() {
// 經銷商商務代號
this.agentUid = "A1234567891002";
// 經銷商金鑰或認證碼
this.agentKey = "nq8KL8qNNCW12A3TBfAp4lU0y3PED8IQ";
// 串接交易位置
this.url = "https://pay.usecase.cc/api/agent";
};
/**
* 取得串接欄位資料
*/
AgentApplicant.prototype.getRawData = function () {
// 範例用檔案
sampleFile = {
size: 273,
type: "image/png",
data: "iVBORw0KGgoAAAANSUhEUgAAADMAAAASCAIAAAB5M3HuAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACmSURBVEhLY/hPe3Dv+1O/ey2LX+96//sTVIgIQD+XQRDx7qO3y4h338C4DILwu28gXQZBuNzHANRGa3To4wU012AiTPcxoKkYWITsvsHlMgiCuG8wugyCBqnLCh5NH3QuA7rpzOfrgyudwd0EAYOi1EBzEwQMcEkb/6Bvx/uTUHWoYMBcBnHT978/oYowwAC4jKCbIICuLiPSTRBAJ5eR5CYQ+P8fAPhjvViKbEtMAAAAAElFTkSuQmCC"
}
// 基本資料
detail = {
project_id: "1",
paymodes: [1, 9],
is_agent_einvoice: 1,
background_return_url: "https://query.usecase.cc/receive.php",
allot_bank_country: 1,
allot_bank_name: 23,
allot_bank_ext: 1872,
allot_bank_idname: "金城武",
allot_bank_id: "12330001144",
allot_bank_currency: "NTD",
service_mail: "[email protected]",
service_phone_type: 1,
service_phone_code: "886",
service_phone: "02-88888888"
}
// 個人
detail.zh_tw_name = "君の名は";
detail.en_us_name = "Your Name";
detail.applicant_name = "金城武";
detail.applicant_id_type = 1;
detail.applicant_id = "M123456789";
detail.applicant_birthday = "20000131";
detail.applicant_zip_code = '432';
detail.applicant_address = "大肚里沙田路二段199號";
detail.applicant_phone_code = "886";
detail.applicant_phone = "04-26888888";
detail.applicant_cellphone_code = '886';
detail.applicant_cellphone = "0924-999999";
detail.applicant_email = "[email protected]";
detail.mcc_code = "1711";
detail.real_zip_code = "407";
detail.real_address = "市政北二路236號26樓之1";
detail.files = {
principal_id_front_img: {
name: "身分證正面.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
},
principal_id_obverse_img: {
name: "身分證反面.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
},
principal_driverlicense_healthidcard_img: {
name: "申請人第二證件.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
},
business_photos_4_img: [
{
name: "營業照片第一張.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
},
{
name: "營業照片第二張.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
},
{
name: "營業照片第三張.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
},
{
name: "營業照片第四張.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
}
],
bank_passbook_img: {
name: "銀行存摺封面影本.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
}
};
/*
// 公司
detail.org_type_uid = 2;
detail.tong_bian = "28915188";
detail.id_name = "高鉅科技股份有限公司";
detail.setup_date = "20081001";
detail.mcc_code = "1711";
detail.capital_currency = "NTD";
detail.capital = 50000000;
detail.zh_tw_name = "MYPAY-小野喵";
detail.en_us_name = "MYPAY - Cat";
detail.zip_code = "407";
detail.address = "市政北二路236號26樓之1";
detail.real_zip_code = "407";
detail.real_address = "市政北二路236號26樓之1";
detail.envoice_zip_code = "407";
detail.envoice_address = "市政北二路236號26樓之1";
detail.principal_name = "金城武";
detail.principal_id_type = 1;
detail.principal_id = "M123456789";
detail.principal_birthday = "20000101";
detail.principal_phone_code = "886";
detail.principal_phone = "04-26888888";
detail.principal_cellphone_code = '886';
detail.principal_cellphone = "0924-999999";
detail.principal_zip_code = "407";
detail.principal_address = "市政北二路236號26樓之1";
detail.principal_email = "[email protected]";
detail.salesman_name = "金城武";
detail.salesman_phone_code = "886";
detail.salesman_phone = "02-8888888";
detail.salesman_cellphone_code = "886";
detail.salesman_cellphone = "0920-999999";
detail.salesman_mail = "[email protected]";
detail.accountant_name = "金城武";
detail.accountant_phone_code = "886";
detail.accountant_phone = "02-8888888";
detail.accountant_fax_code = "886";
detail.accountant_fax = "02-8888887";
detail.accountant_cellphone_code = "886";
detail.accountant_cellphone = "0920-999999";
detail.accountant_mail = "[email protected]";
detail.technician_name = "金城武";
detail.technician_phone_code = "886";
detail.technician_phone = "02-8888888";
detail.technician_cellphone_code = "886";
detail.technician_cellphone = "0920-999999";
detail.technician_mail = "[email protected]";
detail.files = {
principal_id_front_img: {
name: "身分證正面.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
},
principal_id_obverse_img: {
name: "身分證反面.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
},
principal_driverlicense_healthidcard_img: {
name: "負責人第二證件.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
},
approvalletter_img: {
name: "變更事項登記表.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
},
report_401_405_img: {
name: "401報表-108-1.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
},
business_photos_4_img: [{
name: "營業照片第一張.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
}, {
name: "營業照片第二張.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
}, {
name: "營業照片第三張.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
}, {
name: "營業照片第四張.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
}],
bank_passbook_img: {
name: "營業照片第四張.png",
size: sampleFile.size,
type: sampleFile.type,
data: sampleFile.data
}
};*/
return {
agent_uid: this.agentUid,
type: 0,
detail: detail
};
};
/**
* 取得服務位置
*/
AgentApplicant.prototype.getService = function () {
return {
service_name: "store",
cmd: "api/authorizedstore"
};
};
/**
* AES 256 加密
*/
AgentApplicant.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 到主機
*/
AgentApplicant.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();
});
};
/**
* 取得送出欄位資料
*/
AgentApplicant.prototype.getPostData = function () {
return {
"agent_uid": this.agentUid,
"service": this.encrypt(this.getService(), this.agentKey),
"encry_data": this.encrypt(this.getRawData(), this.agentKey)
};
};
/**
* 執行
*/
AgentApplicant.prototype.run = async function () {
json = await this.post(this.getPostData())
console.log(json);
};
AgentApplicant = new AgentApplicant();
AgentApplicant.run();
import json
import base64
import requests
from Crypto.Cipher import AES
from Crypto.Util import Padding
from Crypto.Random import get_random_bytes
"""經銷商串接-特約商店申請
"""
class AgentApplicant:
# 經銷商商務代號
agentUid = "A1234567891002";
# 經銷商金鑰或認證碼
agentKey = b"nq8KL8qNNCW12A3TBfAp4lU0y3PED8IQ";
# 串接交易位置
url = "https://pay.usecase.cc/api/agent"
def getRawData(self):
"""取得串接欄位資料
Returns:
{dict}: 欄位資料
"""
## 範例用檔案
sampleFile = {
'size': 273,
'type': "image/png",
'data': "iVBORw0KGgoAAAANSUhEUgAAADMAAAASCAIAAAB5M3HuAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACmSURBVEhLY/hPe3Dv+1O/ey2LX+96//sTVIgIQD+XQRDx7qO3y4h338C4DILwu28gXQZBuNzHANRGa3To4wU012AiTPcxoKkYWITsvsHlMgiCuG8wugyCBqnLCh5NH3QuA7rpzOfrgyudwd0EAYOi1EBzEwQMcEkb/6Bvx/uTUHWoYMBcBnHT978/oYowwAC4jKCbIICuLiPSTRBAJ5eR5CYQ+P8fAPhjvViKbEtMAAAAAElFTkSuQmCC"
}
## 基本資料
detail = {
'project_id': "1",
'paymodes': [1, 9],
'is_agent_einvoice': 1,
'background_return_url': "https://query.usecase.cc/receive.php",
'allot_bank_country': 1,
'allot_bank_name': 23,
'allot_bank_ext': 1872,
'allot_bank_idname': "金城武",
'allot_bank_id': "12330001144",
'allot_bank_currency': "NTD",
'service_mail': "[email protected]",
'service_phone_type': 1,
'service_phone_code': "886",
'service_phone': "02-88888888"
}
# 個人
personal = {
'zh_tw_name': "君の名は",
'en_us_name': "Your Name",
'applicant_name': "金城武",
'applicant_id_type': 1,
'applicant_id': "M123456789",
'applicant_birthday': "20000131",
'applicant_zip_code': '432',
'applicant_address': "大肚里沙田路二段199號",
'applicant_phone_code': "886",
'applicant_phone': "04-26888888",
'applicant_cellphone_code': '886',
'applicant_cellphone': "0924-999999",
'applicant_email': "[email protected]",
'mcc_code': "1711",
'real_zip_code': "407",
'real_address': "市政北二路236號26樓之1",
'files': {
'principal_id_front_img': {
'name': "身分證正面.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
},
'principal_id_obverse_img': {
'name': "身分證反面.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
},
'principal_driverlicense_healthidcard_img': {
'name': "申請人第二證件.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
},
'business_photos_4_img': [
{
'name': "營業照片第一張.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
},
{
'name': "營業照片第二張.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
},
{
'name': "營業照片第三張.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
},
{
'name': "營業照片第四張.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
}
],
'bank_passbook_img': {
'name': "銀行存摺封面影本.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
}
}
}
detail.update(personal)
"""
# 公司
company = {
'org_type_uid': 2,
'tong_bian': "28915188",
'id_name': "高鉅科技股份有限公司",
'setup_date': "20081001",
'mcc_code': "1711",
'capital_currency': "NTD",
'capital': 50000000,
'zh_tw_name': "MYPAY-小野喵",
'en_us_name': "MYPAY - Cat",
'zip_code': "407",
'address': "市政北二路236號26樓之1",
'real_zip_code': "407",
'real_address': "市政北二路236號26樓之1",
'envoice_zip_code': "407",
'envoice_address': "市政北二路236號26樓之1",
'principal_name': "金城武",
'principal_id_type': 1,
'principal_id': "M123456789",
'principal_birthday': "20000101",
'principal_phone_code': "886",
'principal_phone': "04-26888888",
'principal_cellphone_code': '886',
'principal_cellphone': "0924-999999",
'principal_zip_code': "407",
'principal_address': "市政北二路236號26樓之1",
'principal_email': "[email protected]",
'salesman_name': "金城武",
'salesman_phone_code': "886",
'salesman_phone': "02-8888888",
'salesman_cellphone_code': "886",
'salesman_cellphone': "0920-999999",
'salesman_mail': "[email protected]",
'accountant_name': "金城武",
'accountant_phone_code': "886",
'accountant_phone': "02-8888888",
'accountant_fax_code': "886",
'accountant_fax': "02-8888887",
'accountant_cellphone_code': "886",
'accountant_cellphone': "0920-999999",
'accountant_mail': "[email protected]",
'technician_name': "金城武",
'technician_phone_code': "886",
'technician_phone': "02-8888888",
'technician_cellphone_code': "886",
'technician_cellphone': "0920-999999",
'technician_mail': "[email protected]",
'files': {
'principal_id_front_img': {
'name': "身分證正面.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
},
'principal_id_obverse_img': {
'name': "身分證反面.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
},
'principal_driverlicense_healthidcard_img': {
'name': "負責人第二證件.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
},
'approvalletter_img': {
'name': "變更事項登記表.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
},
'report_401_405_img': {
'name': "401報表-108-1.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
},
'business_photos_4_img': [{
'name': "營業照片第一張.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
}, {
'name': "營業照片第二張.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
}, {
'name': "營業照片第三張.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
}, {
'name': "營業照片第四張.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
}],
'bank_passbook_img': {
'name': "營業照片第四張.png",
'size': sampleFile.get('size'),
'type': sampleFile.get('type'),
'data': sampleFile.get('data')
}
}
}
detail.update(company)
"""
return {
'agent_uid': self.agentUid,
'type': 0,
'detail': detail
}
def getService(self):
"""取得服務位置
Returns:
{dict}: 服務位置資料
"""
return {
'service_name': 'store',
'cmd': 'api/authorizedstore'
}
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)
AgentApplicant = AgentApplicant()
AgentApplicant.run()
串接回傳 JSON 結構如下:
{
"code": "B200",
"msg": "執行成功",
"application_id": 82
}
經銷商發起建立特約商店之請求,審查完畢後,會主動回傳審查結果,若為審核通過,回傳內容中會包含特約商店的商務代號。
使用情境:
經銷商讓所屬店家,可在經銷商自行設計的申請畫面填寫資料,當填寫完畢後,透過API來跟MYPAY建立店家資料,當MYPAY審核完成後,會再通知經銷商審核結果。
- 流程圖 :
建立特約商店參數說明
欄位 | 型態 | 說明 |
---|---|---|
agent_uid | string(16) | 經銷商商務代號 |
service | text | {"service_name": "store", "cmd": "api\/authorizedstore"} JSON格式,AES256加密資料 |
encry_data | text | 『建立特約商店』欄位參考,JSON格式,AES256加密資料 |
『建立特約商店』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
agent_uid | string | 經銷商商務代號 | 必填 |
type | integer | 特約商店類型 | 必填 『特約商店類型』值參考 |
detail | object | 申請詳細內容,請依特約商店類型帶入不同內容 | 必填 『建立特約商店 - 個人資料』欄位參考 『建立特約商店 - 公司資料』欄位參考 |
『建立特約商店』回傳欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
code | string | 交易回傳碼(B200或B500或100) | |
msg | string | 回傳訊息 | |
application_id | integer | 申請編號(狀態B200才有) |
『建立特約商店審核通知』回報欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
code | string | 審核回傳碼(V200審核通過、V500審核拒絕) | |
msg | string | 回傳訊息 | |
memo | string | 審核資訊參考 | |
application_id | integer | 申請編號 | |
biz_id | string | 商務代號(審核回傳碼為V200才有此資訊) |
『特約商店類型』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
0 | integer | 個人 | |
1 | integer | 公司 |
『建立特約商店 - 個人資料』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
project_id | integer | 申請項目ID | 必填 『特約商店申請項目 - 個人』值參考 |
paymodes | array | 申請開通付款方式 | 必填 每筆『第三方支付(代收付)付款方式 - 個人』欄位參考 每筆『第四方支付付款方式 - 個人』欄位參考 每筆『聚合收款碼付款方式 - 個人』欄位參考 每筆『39buy購物車付款方式 - 個人』欄位參考 每筆『智慧點餐付款方式 - 個人』欄位參考 每筆『實體刷卡機付款方式 - 個人』欄位參考 每筆『計程車專用收款碼付款方式 - 個人』欄位參考 |
is_online_payment | integer | 智慧點餐-申請線上支付功能(預設不申請) | 『是否申請線上支付功能』值參考 |
is_einvoice | integer | 申請特約商店電子發票(個人類型不可申請) | 『是否申請電子發票』值參考 |
is_agent_einvoice | integer | 經銷商代開電子發票 | 『經銷商代開電子發票』值參考 |
background_return_url | string | 審核完成後,回報網址(限https網址與443port) | |
allot_bank_country | string | 撥款帳戶預設國別 參考JSON資料 |
必填 |
allot_bank_name | string | 撥款預設行行庫名 參考JSON資料 |
必填 |
allot_bank_ext | string | 撥款預設銀行分行 參考JSON資料 |
必填 |
allot_bank_idname | string | 撥款預設銀行戶名 | 必填 |
allot_bank_id | string | 撥款預設銀行帳號 | 必填 |
allot_bank_currency | string | 撥款帳戶預設幣別 | 必填 『資本幣別』值參考 |
allot_bank_swift_code | string | SwiftCode | |
service_mail | string | 客服 E-mail | 必填 |
service_phone_type | integer | 服務電話類型1.電話 2.手機 3.Line | 必填 『服務電話類型』值參考 |
service_phone_code | string | 服務電話國碼(LINE可忽略) | |
service_phone | string | 服務電話或LINE 電話格式:02-27000000 手機格式:0918-888888 LINE格式:@lineid |
必填 |
website_url | string | 特店網址(若為網路商店類型之特約商店,此欄位務必填寫) | |
zh_tw_name | string | 國內交易名稱(中、英文不拘) | 必填 |
en_us_name | string | 國外交易名稱(英文) | 必填 |
applicant_name | string | 申請人姓名 | 必填 |
applicant_id_type | integer | 申請人證號類型 | 必填 『證號類型』值參考 |
applicant_id | string | 申請人身分證/統一證號/護照號碼 | 必填 |
applicant_birthday | string | 申請人生日(格式YYYYMMDD) | 必填 |
applicant_issue_date | string | 申請人身分證發證日期(格式YYYMMDD民國年如民國95年為0950214) | |
applicant_issue_place | string | 申請人身分證發證地點碼 參考JSON資料 |
|
applicant_issue_type | string | 申請人領補發類型碼 參考JSON資料 |
|
applicant_email | string | 申請人 EMail | 必填 |
applicant_phone_code | string | 申請人電話國碼 | 必填 |
applicant_phone | string | 申請人電話 | 必填 |
applicant_cellphone_code | string | 申請人手機國碼 | 必填 |
applicant_cellphone | string | 申請人手機 | 必填 |
applicant_zip_code | string | 申請人戶籍地址-郵遞區號(主要辨識) | 必填 |
applicant_city_code | string | 申請人戶籍地址-縣市(參考用) | |
applicant_district_code | string | 申請人戶籍地址-鄉鎮市區(參考用) | |
applicant_address | string | 申請人戶籍地址 (必須排除縣市與鄉鎮市區資訊) | 必填 |
mcc_code | string | MCC碼(產業類別) 參考JSON資料 |
必填 |
real_zip_code | string | 實際營業郵遞區號 | 必填 |
real_city_code | string | 實際營業縣市 | |
real_district_code | string | 實際營業區域 | |
real_address | string | 實際營業地址(必須排除縣市與鄉鎮市區資訊) | 必填 |
envoice_zip_code | string | 發票寄送郵遞區號 | |
envoice_city_code | string | 發票寄送縣市 | |
envoice_district_code | string | 發票寄送區域 | |
envoice_address | string | 發票寄送地址(必須排除縣市與鄉鎮市區資訊) | |
files | object | 附件檔案(全部POST資料量需小於36MB) 若專案申請項目ID為8則使用計程車專用收款碼附件檔案 若專案申請項目ID為其於則使用一般個人附件檔案 僅支援上傳pdf,png,jpeg,jpg檔案 type為下列清單: application/x-pdf application/pdf image/png image/jpeg application/x-jpg application/x-jpe |
必填 『個人附件檔案』欄位參考 『計程車專用收款碼附件檔案』欄位參考 |
『建立特約商店 - 公司資料』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
project_id | integer | 申請項目ID | 必填 『特約商店申請項目 - 公司』值參考 |
paymodes | array | 申請開通付款方式 | 必填 每筆『第三方支付(代收付)付款方式 - 公司』欄位參考 每筆『第四方支付付款方式 - 公司』欄位參考 每筆『聚合收款碼付款方式 - 公司』欄位參考 每筆『39buy購物車付款方式 - 公司』欄位參考 每筆『想就捐慈善勸募系統付款方式 - 公司』欄位參考 每筆『智慧點餐付款方式 - 公司』欄位參考 每筆『實體刷卡機付款方式 - 公司』欄位參考 |
is_online_payment | integer | 智慧點餐-申請線上支付功能(預設不申請) | 『是否申請線上支付功能』值參考 |
is_einvoice | integer | 申請特約商店電子發票(個人類型不可申請) | 『是否申請電子發票』值參考 |
is_agent_einvoice | integer | 經銷商代開電子發票 | 『經銷商代開電子發票』值參考 |
background_return_url | string | 審核完成後,回報網址(限https網址與443port) | |
allot_bank_country | string | 撥款帳戶預設國別 參考JSON資料 |
必填 |
allot_bank_name | string | 撥款預設行行庫名 參考JSON資料 |
必填 |
allot_bank_ext | string | 撥款預設銀行分行 參考JSON資料 |
必填 |
allot_bank_idname | string | 撥款預設銀行戶名 | 必填 |
allot_bank_id | string | 撥款預設銀行帳號 | 必填 |
allot_bank_currency | string | 撥款帳戶預設幣別 | 必填 『資本幣別』值參考 |
allot_bank_swift_code | string | SwiftCode | |
service_mail | string | 客服 E-mail | 必填 |
service_phone_type | integer | 服務電話類型1.電話 2.手機 3.Line | 必填 『服務電話類型』值參考 |
service_phone_code | string | 服務電話國碼(LINE可忽略) | |
service_phone | string | 服務電話或LINE 電話格式:02-27000000 手機格式:0918-888888 LINE格式:@lineid |
必填 |
website_url | string | 特店網址(若為網路商店類型之特約商店,此欄位務必填寫) | |
org_type_uid | integer | 組織型態 | 必填 『組織型態』值參考 |
tong_bian | string | 統編 | 必填 |
id_name | string | 執照名稱 | 必填 |
setup_date | string | 設立日期(格式YYYYMMDD) | 必填 |
mcc_code | string | MCC碼(產業類別) 參考JSON資料 |
必填 |
capital_currency | string | 資本幣別 | 必填 『資本幣別』值參考 |
capital | string | 資本額 | 必填 |
zh_tw_name | string | 國內交易名稱(中、英文不拘) | 必填 |
en_us_name | string | 國外交易名稱(英文) | 必填 |
zip_code | string | 公司登記郵遞區號 | 必填 |
city_code | string | 公司登記縣市 | |
district_code | string | 公司登記區域 | |
address | string | 公司登記地址(必須排除縣市與鄉鎮市區資訊) | 必填 |
real_zip_code | string | 實際營業郵遞區號 | 必填 |
real_city_code | string | 實際營業縣市 | |
real_district_code | string | 實際營業區域 | |
real_address | string | 實際營業地址(必須排除縣市與鄉鎮市區資訊) | 必填 |
envoice_zip_code | string | 公司發票寄送郵遞區號 | 必填 |
envoice_city_code | string | 公司發票寄送縣市 | |
envoice_district_code | string | 公司發票寄送區域 | |
envoice_address | string | 公司發票寄送地址(必須排除縣市與鄉鎮市區資訊) | 必填 |
principal_name | string | 登記負責人姓名 | 必填 |
principal_id_type | integer | 1:身分證,2:統一證號,3:護照號碼. 負責人為本國人為1,外國人2 or 3 | 必填 『證號類型』值參考 |
principal_id | string | 登記負責人身分證/統一證號/護照號碼 | 必填 |
principal_birthday | string | 登記負責人生日(格式YYYYMMDD) | 必填 |
principal_issue_date | string | 登記負責人身分證發證日期(格式YYYMMDD民國年如民國95年為0950214) | |
principal_issue_place | string | 登記負責人身分證發證地點碼 參考JSON資料 |
|
principal_issue_type | string | 登記負責人領補發類型碼 參考JSON資料 |
|
principal_phone_code | string | 登記負責人電話國碼 | 必填 |
principal_phone | string | 登記負責人電話 | 必填 |
principal_cellphone_code | string | 登記負責人手機國碼 | 必填 |
principal_cellphone | string | 登記負責人手機 | 必填 |
principal_zip_code | string | 登記負責人郵遞區號 | 必填 |
principal_city_code | string | 登記負責人戶籍縣市 | |
principal_district_code | string | 登記負責人戶籍區域 | |
principal_address | string | 登記負責人戶籍地址 | 必填 |
principal_email | string | 登記負責人信箱 | 必填 |
salesman_name | string | 特店業務姓名 | 必填 |
salesman_phone_code | string | 特店業務電話國碼 | 必填 |
salesman_phone | string | 特店業務電話 | 必填 |
salesman_ext | string | 特店業務分機 | |
salesman_cellphone_code | string | 特店業務手機國碼 | 必填 |
salesman_cellphone | string | 特店業務手機 | 必填 |
salesman_mail | string | 特店業務信箱 | 必填 |
accountant_name | string | 特店帳務人員姓名 | 必填 |
accountant_phone_code | string | 特店帳務人員電話國碼 | 必填 |
accountant_phone | string | 特店帳務人員電話 | 必填 |
accountant_ext | string | 特店帳務人員分機 | |
accountant_cellphone_code | string | 特店帳務人員手機國碼 | 必填 |
accountant_cellphone | string | 特店帳務人員手機 | 必填 |
accountant_mail | string | 特店帳務人員信箱 | 必填 |
accountant_fax_code | string | 特店帳務人員傳真國碼 | |
accountant_fax | string | 特店帳務人員傳真 | |
technician_name | string | 特店技術人員姓名 | 必填 |
technician_phone_code | string | 特店技術人員電話國碼 | 必填 |
technician_phone | string | 特店技術人員電話 | 必填 |
technician_ext | string | 特店技術人員分機 | |
technician_cellphone_code | string | 特店技術人員手機國碼 | 必填 |
technician_cellphone | string | 特店技術人員手機 | 必填 |
technician_mail | string | 特店技術人員信箱 | 必填 |
files | object | 附件檔案(全部POST資料量需小於36MB) 若專案申請項目ID為5則使用慈善附件檔案 若專案申請項目ID為其於則使用一般公司附件檔案 僅支援上傳pdf,png,jpeg,jpg檔案 type為下列清單: application/x-pdf application/pdf image/png image/jpeg application/x-jpg application/x-jpe |
必填 『一般公司附件檔案』欄位參考 『慈善附件檔案』欄位參考 |
『特約商店申請項目 - 個人』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 第三方支付(代收付) | MYPAY代收付 |
2 | integer | 第四方支付 | 申請銀行特約商店,MYPAY不代收 |
3 | integer | 聚合收款碼 | 需搭配第三方或第四方支付 |
4 | integer | 39Buy購物車 | 需搭配第三方或第四方支付 |
6 | integer | 智慧點餐 | |
7 | integer | 實體刷卡機 | 需搭配第三方或第四方支付 |
8 | integer | 計程車專用收款碼 | 需搭配第三方或第四方支付 |
『第三方支付(代收付)付款方式 - 個人』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 信用卡 | |
3 | integer | 超商代碼 | |
4 | integer | WEBATM | |
6 | integer | 虛擬帳號 | |
7 | integer | 銀聯卡 | |
9 | integer | 海外信用卡 | |
10 | integer | 支付寶 | |
33 | integer | 支付寶線下 | |
15 | integer | LINE Pay線上付款 | |
16 | integer | LINE Pay線下付款 | |
27 | integer | Pi 拍錢包線上 | |
28 | integer | Pi 拍錢包線下 | |
38 | integer | 悠遊付線上 | |
39 | integer | 悠遊付線下 |
『第四方支付付款方式 - 個人』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 信用卡 | |
3 | integer | 超商代碼 | |
4 | integer | WEBATM | |
6 | integer | 虛擬帳號 | |
7 | integer | 銀聯卡 | |
9 | integer | 海外信用卡 | |
10 | integer | 支付寶 | |
33 | integer | 支付寶線下 | |
15 | integer | LINE Pay線上付款 | |
16 | integer | LINE Pay線下付款 | |
27 | integer | Pi 拍錢包線上 | |
28 | integer | Pi 拍錢包線下 | |
38 | integer | 悠遊付線上 | |
39 | integer | 悠遊付線下 |
『聚合收款碼付款方式 - 個人』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 信用卡 | |
3 | integer | 超商代碼 | |
4 | integer | WEBATM | |
6 | integer | 虛擬帳號 | |
7 | integer | 銀聯卡 | |
9 | integer | 海外信用卡 | |
10 | integer | 支付寶 | |
33 | integer | 支付寶線下 | |
15 | integer | LINE Pay線上付款 | |
16 | integer | LINE Pay線下付款 | |
27 | integer | Pi 拍錢包線上 | |
28 | integer | Pi 拍錢包線下 | |
38 | integer | 悠遊付線上 | |
39 | integer | 悠遊付線下 |
『39buy購物車付款方式 - 個人』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 信用卡 | |
3 | integer | 超商代碼 | |
4 | integer | WEBATM | |
6 | integer | 虛擬帳號 | |
7 | integer | 銀聯卡 | |
9 | integer | 海外信用卡 | |
10 | integer | 支付寶 | |
33 | integer | 支付寶線下 | |
15 | integer | LINE Pay線上付款 | |
16 | integer | LINE Pay線下付款 | |
27 | integer | Pi 拍錢包線上 | |
28 | integer | Pi 拍錢包線下 | |
38 | integer | 悠遊付線上 | |
39 | integer | 悠遊付線下 |
『智慧點餐付款方式 - 個人』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 信用卡 | |
3 | integer | 超商代碼 | |
4 | integer | WEBATM | |
6 | integer | 虛擬帳號 | |
7 | integer | 銀聯卡 | |
9 | integer | 海外信用卡 | |
10 | integer | 支付寶 | |
33 | integer | 支付寶線下 | |
15 | integer | LINE Pay線上付款 | |
16 | integer | LINE Pay線下付款 | |
27 | integer | Pi 拍錢包線上 | |
28 | integer | Pi 拍錢包線下 | |
38 | integer | 悠遊付線上 | |
39 | integer | 悠遊付線下 |
『實體刷卡機付款方式 - 個人』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 信用卡 | |
9 | integer | 海外信用卡 | |
10 | integer | 支付寶 | |
12 | integer | 行動ATM | |
15 | integer | LINE Pay線上付款 | |
16 | integer | LINE Pay線下付款 |
『計程車專用收款碼付款方式 - 個人』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 信用卡 | |
7 | integer | 銀聯卡 | |
9 | integer | 海外信用卡 | |
10 | integer | 支付寶 | |
33 | integer | 支付寶線下 | |
15 | integer | LINE Pay線上付款 | |
16 | integer | LINE Pay線下付款 | |
27 | integer | Pi 拍錢包線上 | |
28 | integer | Pi 拍錢包線下 |
『是否申請線上支付功能』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
0 | integer | 不申請 | |
1 | integer | 申請 |
『是否申請電子發票』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
0 | integer | 不申請 | |
1 | integer | 申請 |
『經銷商代開電子發票』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
0 | integer | 不代開 | |
1 | integer | 代開 |
『資本幣別』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
NTD | string | 台幣 | |
USD | string | 美元 | |
CNY | string | 人民幣 | |
HKD | string | 港幣 | |
JPY | string | 日圓 | |
EUR | string | 歐元 |
『服務電話類型』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 電話 | |
2 | integer | 手機 | |
3 | integer | LINE |
『證號類型』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 身份證字號(預設) | |
2 | integer | 統一證號 | |
3 | integer | 護照號碼 |
『個人附件檔案』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
principal_id_front_img | object | 申請人身分證正面 | 必填 『夾檔檔案資訊』欄位參考 |
principal_id_obverse_img | object | 申請人身分證反面 | 必填 『夾檔檔案資訊』欄位參考 |
principal_driverlicense_healthidcard_img | object | 申請人第二證件『有照片之駕照、健保卡』(擇一) | 必填 『夾檔檔案資訊』欄位參考 |
business_photos_4_img | array | 營業照片4張(包含1.地址門牌 2.招牌 3.營業項目或價目表 4.營業場所現況照片) | 必填 每筆『夾檔檔案資訊』欄位參考 |
bank_passbook_img | object | 銀行存摺封面影本 | 必填 『夾檔檔案資訊』欄位參考 |
『計程車專用收款碼附件檔案』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
principal_id_front_img | object | 申請人身分證正面 | 必填 『夾檔檔案資訊』欄位參考 |
principal_id_obverse_img | object | 申請人身分證反面 | 必填 『夾檔檔案資訊』欄位參考 |
principal_driverlicense_healthidcard_img | object | 申請人第二證件『健保卡』 | 必填 『夾檔檔案資訊』欄位參考 |
business_photos_2_img | array | 營業照片2張(包含 1.職業駕照 2.計程車執業登記證) | 必填 每筆『夾檔檔案資訊』欄位參考 |
bank_passbook_img | object | 銀行存摺封面影本 | 必填 『夾檔檔案資訊』欄位參考 |
『特約商店申請項目 - 公司』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 第三方支付(代收付) | MYPAY代收付 |
2 | integer | 第四方支付 | 申請銀行特約商店,MYPAY不代收 |
3 | integer | 聚合收款碼 | 需搭配第三方或第四方支付 |
4 | integer | 39Buy購物車 | 需搭配第三方或第四方支付 |
5 | integer | 想就捐慈善勸募系統 | 需搭配第三方或第四方支付 |
6 | integer | 智慧點餐 | |
7 | integer | 實體刷卡機 | 需搭配第三方或第四方支付 |
『第三方支付(代收付)付款方式 - 公司』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 信用卡 | |
3 | integer | 超商代碼 | |
4 | integer | WEBATM | |
6 | integer | 虛擬帳號 | |
7 | integer | 銀聯卡 | |
9 | integer | 海外信用卡 | |
20 | integer | APPLE PAY | |
21 | integer | Google Pay | |
10 | integer | 支付寶 | |
33 | integer | 支付寶線下 | |
13 | integer | 微信支付 | |
19 | integer | 微信支付線下 | |
15 | integer | LINE Pay線上付款 | |
16 | integer | LINE Pay線下付款 | |
27 | integer | Pi 拍錢包線上 | |
28 | integer | Pi 拍錢包線下 | |
38 | integer | 悠遊付線上 | |
39 | integer | 悠遊付線下 |
『第四方支付付款方式 - 公司』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 信用卡 | |
3 | integer | 超商代碼 | |
4 | integer | WEBATM | |
6 | integer | 虛擬帳號 | |
7 | integer | 銀聯卡 | |
9 | integer | 海外信用卡 | |
10 | integer | 支付寶 | |
33 | integer | 支付寶線下 | |
13 | integer | 微信支付 | |
19 | integer | 微信支付線下 | |
15 | integer | LINE Pay線上付款 | |
16 | integer | LINE Pay線下付款 | |
20 | integer | APPLE PAY | |
21 | integer | Google Pay | |
27 | integer | Pi 拍錢包線上 | |
28 | integer | Pi 拍錢包線下 | |
29 | integer | 美國運通 | |
38 | integer | 悠遊付線上 | |
39 | integer | 悠遊付線下 |
『聚合收款碼付款方式 - 公司』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 信用卡 | |
3 | integer | 超商代碼 | |
4 | integer | WEBATM | |
6 | integer | 虛擬帳號 | |
7 | integer | 銀聯卡 | |
9 | integer | 海外信用卡 | |
10 | integer | 支付寶 | |
33 | integer | 支付寶線下 | |
13 | integer | 微信支付 | |
19 | integer | 微信支付線下 | |
15 | integer | LINE Pay線上付款 | |
16 | integer | LINE Pay線下付款 | |
20 | integer | APPLE PAY | |
21 | integer | Google Pay | |
27 | integer | Pi 拍錢包線上 | |
28 | integer | Pi 拍錢包線下 | |
38 | integer | 悠遊付線上 | |
39 | integer | 悠遊付線下 |
『39buy購物車付款方式 - 公司』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 信用卡 | |
3 | integer | 超商代碼 | |
4 | integer | WEBATM | |
6 | integer | 虛擬帳號 | |
7 | integer | 銀聯卡 | |
9 | integer | 海外信用卡 | |
10 | integer | 支付寶 | |
33 | integer | 支付寶線下 | |
13 | integer | 微信支付 | |
19 | integer | 微信支付線下 | |
15 | integer | LINE Pay線上付款 | |
16 | integer | LINE Pay線下付款 | |
20 | integer | APPLE PAY | |
21 | integer | Google Pay | |
27 | integer | Pi 拍錢包線上 | |
28 | integer | Pi 拍錢包線下 | |
29 | integer | 美國運通 | |
38 | integer | 悠遊付線上 | |
39 | integer | 悠遊付線下 |
『想就捐慈善勸募系統付款方式 - 公司』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 信用卡 | |
3 | integer | 超商代碼 | |
4 | integer | WEBATM | |
6 | integer | 虛擬帳號 | |
7 | integer | 銀聯卡 | |
9 | integer | 海外信用卡 | |
10 | integer | 支付寶 | |
33 | integer | 支付寶線下 | |
13 | integer | 微信支付 | |
19 | integer | 微信支付線下 | |
15 | integer | LINE Pay線上付款 | |
16 | integer | LINE Pay線下付款 | |
20 | integer | APPLE PAY | |
21 | integer | Google Pay | |
27 | integer | Pi 拍錢包線上 | |
28 | integer | Pi 拍錢包線下 | |
29 | integer | 美國運通 | |
38 | integer | 悠遊付線上 | |
39 | integer | 悠遊付線下 |
『智慧點餐付款方式 - 公司』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 信用卡 | |
3 | integer | 超商代碼 | |
4 | integer | WEBATM | |
6 | integer | 虛擬帳號 | |
7 | integer | 銀聯卡 | |
9 | integer | 海外信用卡 | |
10 | integer | 支付寶 | |
33 | integer | 支付寶線下 | |
13 | integer | 微信支付 | |
19 | integer | 微信支付線下 | |
15 | integer | LINE Pay線上付款 | |
16 | integer | LINE Pay線下付款 | |
20 | integer | APPLE PAY | |
21 | integer | Google Pay | |
27 | integer | Pi 拍錢包線上 | |
28 | integer | Pi 拍錢包線下 | |
29 | integer | 美國運通 | |
38 | integer | 悠遊付線上 | |
39 | integer | 悠遊付線下 |
『實體刷卡機付款方式 - 公司』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
1 | integer | 信用卡 | |
9 | integer | 海外信用卡 | |
10 | integer | 支付寶 | |
12 | integer | 行動ATM | |
13 | integer | 微信支付 | |
19 | integer | 微信支付線下 | |
15 | integer | LINE Pay線上付款 | |
16 | integer | LINE Pay線下付款 |
『組織型態』值內容
值 | 型態 | 說明 | 備註 |
---|---|---|---|
0 | integer | 0:財團法人 | |
1 | integer | 1:社團法人 | |
2 | integer | 2:股份有限公司 | |
3 | integer | 3:有限公司 | |
4 | integer | 4:商行商號 |
『一般公司附件檔案』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
principal_id_front_img | object | 負責人身分證正面 | 必填 『夾檔檔案資訊』欄位參考 |
principal_id_obverse_img | object | 負責人身分證反面 | 必填 『夾檔檔案資訊』欄位參考 |
principal_driverlicense_healthidcard_img | object | 負責人第二證件『有照片之駕照、健保卡』(擇一) | 必填 『夾檔檔案資訊』欄位參考 |
approvalletter_img | object | 變更事項登記表、核準函(檔案類型:pdf) | 必填 『夾檔檔案資訊』欄位參考 |
report_401_405_img | object | 近一期401報表 或 405報表 或 創立未滿6個月,無此資料 | 『夾檔檔案資訊』欄位參考 |
business_photos_4_img | array | 營業照片4張(包含1.地址門牌 2.招牌 3.營業項目或價目表 4.營業場所現況照片) | 必填 每筆『夾檔檔案資訊』欄位參考 |
bank_passbook_img | object | 銀行存摺封面影本 | 必填 『夾檔檔案資訊』欄位參考 |
『慈善附件檔案』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
principal_id_front_img | object | 負責人身分證正面 | 必填 『夾檔檔案資訊』欄位參考 |
principal_id_obverse_img | object | 負責人身分證反面 | 必填 『夾檔檔案資訊』欄位參考 |
principal_driverlicense_healthidcard_img | object | 負責人第二證件『有照片之駕照、健保卡』(擇一) | 必填 『夾檔檔案資訊』欄位參考 |
legal_person_registration_documents_img | object | 法人登記文件 | 必填 『夾檔檔案資訊』欄位參考 |
donation_charter_img | object | 捐助章程 | 必填 『夾檔檔案資訊』欄位參考 |
business_photos_4_img | array | 營業照片4張(包含地址、店名) | 必填 每筆『夾檔檔案資訊』欄位參考 |
bank_passbook_img | object | 銀行存摺封面影本 | 必填 『夾檔檔案資訊』欄位參考 |
『夾檔檔案資訊』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
name | string | 檔案名稱 | 必填 |
size | integer | 檔案大小 | 必填 |
type | string | 檔案格式 | 必填 |
data | string | 原始檔案內容(Base64格式) | 必填 |
建立特約商店申請網址請求
<?php
/**
* 經銷商串接-建立特約商店申請網址
*/
final class AgentEntranceApplicant
{
/**
* 經銷商商務代號
* @var string
*/
public $agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
* @var string
*/
public $agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 串接交易位置
* @var string
*/
public $url = "https://pay.usecase.cc/api/agent";
/**
* 取得串接欄位資料
* @return array
*/
public function getRawData()
{
$rawData = array();
$rawData['agent_uid'] = "289151881003";
$rawData['code'] = "20221221000002";
return $rawData;
}
/**
* 取得服務位置
* @return array
*/
public function getService()
{
return array(
'service_name' => 'store',
'cmd' => 'api/authorizedentrancestore'
);
}
/**
* 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;
}
}
$AgentEntranceApplicant = new AgentEntranceApplicant();
$AgentEntranceApplicant->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 AgentEntranceApplicant {
/// <summary>
/// 經銷商商務代號
/// </summary>
public string agentUid = "518169081001";
/// <summary>
/// 經銷商金鑰或認證碼
/// </summary>
public string agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/// <summary>
/// 串接交易位置
/// </summary>
public string url = "https://pay.usecase.cc/api/agent";
/// <summary>
/// 執行
/// </summary>
static void Main() {
AgentEntranceApplicant simulator = new AgentEntranceApplicant();
//僅限走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.agent_uid = "289151881003";
rawData.code = "20221221000002";
return rawData;
}
/// <summary>
/// 取得服務位置
/// </summary>
private ServiceRequest GetService() {
ServiceRequest rawData = new ServiceRequest();
rawData.service_name = "store";
rawData.cmd = "api/authorizedentrancestore";
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 AgentEntranceApplicant {
/**
* 經銷商商務代號
*/
String agentUid = "518169081001";
/**
* 經銷商金鑰或認證碼
*/
String agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
/**
* 串接交易位置
*/
String url = "https://pay.usecase.cc/api/agent";
/**
* 執行
* @param args
*/
public static void main(String[] args) {
AgentEntranceApplicant simulator = new AgentEntranceApplicant();
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("agent_uid", "289151881003");
rawData.put("code", "20221221000002");
return rawData;
}
/**
* 取得服務位置
* @return 串接服務資料
*/
public Map getService() {
Map<Object, Object> rawData = new HashMap<Object, Object>();
rawData.put("service_name", "store");
rawData.put("cmd", "api/authorizedentrancestore");
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 AgentEntranceApplicant() {
// 經銷商商務代號
this.agentUid = "518169081001";
// 經銷商金鑰或認證碼
this.agentKey = "0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
// 串接交易位置
this.url = "https://pay.usecase.cc/api/agent";
};
/**
* 取得串接欄位資料
*/
AgentEntranceApplicant.prototype.getRawData = function () {
return {
agent_uid: "289151881003",
code: "20221221000002",
};
};
/**
* 取得服務位置
*/
AgentEntranceApplicant.prototype.getService = function () {
return {
service_name: "store",
cmd: "api/authorizedentrancestore"
};
};
/**
* AES 256 加密
*/
AgentEntranceApplicant.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 到主機
*/
AgentEntranceApplicant.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();
});
};
/**
* 取得送出欄位資料
*/
AgentEntranceApplicant.prototype.getPostData = function () {
return {
"agent_uid": this.agentUid,
"service": this.encrypt(this.getService(), this.agentKey),
"encry_data": this.encrypt(this.getRawData(), this.agentKey)
};
};
/**
* 執行
*/
AgentEntranceApplicant.prototype.run = async function () {
json = await this.post(this.getPostData())
console.log(json);
};
AgentEntranceApplicant = new AgentEntranceApplicant();
AgentEntranceApplicant.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 AgentEntranceApplicant:
# 經銷商商務代號
agentUid = "518169081001";
# 經銷商金鑰或認證碼
agentKey = b"0DZP5XgV1dLXXNQqNUFZ7UXvSP6DBalS";
# 串接交易位置
url = "https://pay.usecase.cc/api/agent"
def getRawData(self):
"""取得串接欄位資料
Returns:
{dict}: 欄位資料
"""
rawData = {
'agent_code': "289151881003",
'code': "20221221000002",
}
return rawData
def getService(self):
"""取得服務位置
Returns:
{dict}: 服務位置資料
"""
return {
'service_name': 'store',
'cmd': 'api/authorizedentrancestore'
}
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)
AgentEntranceApplicant = AgentEntranceApplicant()
AgentEntranceApplicant.run()
串接回傳 JSON 結構如下:
{
"code": "B200",
"msg": "執行成功",
"url": "http:\/\/xxxxx\/xxxxxx\/xxxxxx\/xxxxxxx"
}
經銷商發起建立特約商店申請網址請求,請求資料無誤後,將回傳一組網址供特約商店進行線上申請,審查完畢後,會主動回傳審查結果,若為審核通過,回傳內容中會包含特約商店的唯一代碼。
使用情境:
經銷商希望所屬店家透過MYPAY的申請頁面來填寫,並且希望知道該申請者為何,可以使用該API取得一組屬於商家的專屬申請網址。
注意事項:
1 .當MYPAY已接收到該申請網址的資料時,不可再度使用
2 .當審查結束後,MYPAY會將審查結果告知經銷商,通知內容要點為MYPAY給予的商務代號即在申請網址時的唯一碼
- 流程圖 :
建立特約商店申請網址參數說明
欄位 | 型態 | 說明 |
---|---|---|
agent_uid | string(16) | 經銷商商務代號 |
service | text | {"service_name": "store", "cmd": "api\/authorizedstore"} JSON格式,AES256加密資料 |
encry_data | text | 『建立特約商店申請網址』欄位參考,JSON格式,AES256加密資料 |
『建立特約商店申請網址』欄位
參數名稱 | 型態 | 說明 | 必須 |
---|---|---|---|
agent_uid | string | 經銷商商務代號 | 必填 |
code | string | 申請代號(不可重複) | 必填 |
『建立特約商店申請網址』回傳欄位
參數名稱 | 型態 | 說明 |
---|---|---|
code | string | 交易回傳碼(200或100) |
msg | string | 回傳訊息 |
url | string | 線上申請網址(狀態200才有) |
agent_code | string | 店家唯一碼(狀態200才有) |
『建立特約商店申請網址審核通知』回報欄位
參數名稱 | 型態 | 說明 |
---|---|---|
code | string | 審核回傳碼(V200審核通過、V500審核拒絕) |
msg | string | 回傳訊息 |
memo | string | 審核資訊參考 |
agent_code | string | 店家唯一碼 |
biz_id | string | 商務代號(審核回傳碼為V200才有此資訊) |
附錄一:模擬串接列表
「線上建立」驗證機制,提供模擬使用HTTP Protocol,透過POST方式傳遞資料到MYPAY, 並且得到回傳結果。
附錄二:狀態代碼
以下回傳的狀態代碼均須處理,避免系統連線錯誤,MYPAY LINK回傳時,貴司系統無法判讀
狀態代碼 | 狀態說明 | 詳細說明 |
---|---|---|
100 | 資料錯誤 | MYPAYLINK收到資料,但是格式或資料錯誤 |
400 | 系統錯誤訊息 | 若MYPAY LINK或上游服務商系統異常時 |
B200 | 執行成功 | 處理成功執行 |
B500 | 執行失敗 | 處理時,資料異常不予以處理 |
V200 | 審核通過或驗證通過 | 收到資料為已確認,並告知結果 |
V500 | 審核拒絕或驗證失敗 | 收到資料為不合規,並告知結果 |
附錄三:金鑰異動
- 金鑰重新發送與變更
附錄四:資料加密方式說明
- 所有的API送出HTTPs請求之欄位中,service 和 encry_data 欄位皆進行 AES256+BASE64 加密處理。
- AES加密,格式為CBC,長度為256bits,金鑰長度32,IV長度16,傳遞內文為加密後組合IV並經過Base64轉換後傳出。
- IV資料建議隨機產生。
PHP加密示意:
AesEncrypt -> base64_ecode($IV . $JSON)
C#加密示意:
AesEncrypt -> (bytes)IV+(bytes)Json -> toBase64
Java加密示意:
AesEncrypt -> (bytes)IV+(bytes)Json -> toBase64
Node.js加密示意:
AesEncrypt -> concat([IV,JSON], [IV_SIZE,JSON_SIZE]) -> toString('base64')
Python加密示意:
AesEncrypt -> (bytes)IV+(bytes)Json -> base64.b64encode
附錄五:審核完成網址通知
- 當我司審核通過或失敗,才會通知