[C#] 實現 TabPay 金流平台的快速信用卡支付整合(保留卡片) - Pay By Card Token

2024-09-04

接續上一篇文章,這也是為何主要最後選 TabPay 的原因,因為他可以保存住客戶的信用卡授權

然後再次進行刷卡,但是得先取得授權並且保存著,這時候要使用的就是 Pay by Card Token



1. 你得先參考 之前這篇文章 實現 TabPay 金流平台的快速信用卡支付整合 - Get Prime 中間的步驟,拿到

Partner Key 跟 APP Key ,還有裡面取的 Prime  的方式,那一段是一樣的

sandbox 測試卡號 4242424242424242 時間 04/29 , CSV: 123

HTML + Javascript Code:

<script src="https://js.tappaysdk.com/tpdirect/v5.1.0"></script>
<script>TPDirect.setupSDK('153376', 'appkey_blog_step2', 'sandbox')</script>
<form method="post" id="formMain" enctype="multipart/form-data" onsubmit="Splash1()">
<div>
<label>請輸入卡號</label>
<p>
<div id="cardview-container"></div>
</p>
<p>
<button type="button" onclick="onClick()">Get Prime By Javascript</button>
</p>
<p>
<textarea asp-for="Prime" name="Prime" id="Prime" style="width:100%">
</textarea>
</p>
<p>
<button id="btnSubmit" asp-page-handler="Save" style="width: 200px;" class="btn btn-success pull-right"><i class="fa fa-save" aria-hidden="true"></i> &nbsp;Pay by Prime</button>
</p>
</div>
<div style="color:red" id="divResult">
@Model.Result
</div>
</form>
<script>
function onClick() {
toastr.success($('#cc-number').val());
TPDirect.card.getPrime(function (result) {
console.log(result);
//取得結果顯示出來
$('#Prime').val(JSON.stringify(result));
$('#divResult').html(JSON.stringify(result));
})
}
var defaultCardViewStyle = {
color: 'rgb(0,0,0)',
fontSize: '24px',
lineHeight: '50px',
fontWeight: '300',
errorColor: 'red',
placeholderColor: ''
};
TPDirect.card.setup('#cardview-container', defaultCardViewStyle, {
isUsedCcv: true
})
TPDirect.card.onUpdate(function (update) {
if (update.canGetPrime) {
console.log('success log');
} else {
}
if (update.hasError) {
cardViewContainer.classList.add('error')
} else {
cardViewContainer.classList.remove('error')
}
if (update.status.number) {
showErrorMessage('Please check your credit card number')
} else {
hideErrorMessage()
}
})
/* Prime Result
{
"status": 0,
"msg": "Success",
"card": {
"prime": "407475a665e5a772f7ea2b27c592292ba6f3137d6cc4b1cde49f6b8017acd66d",
"issuer": "",
"lastfour": "4242",
"bincode": "424242",
"funding": 0,
"type": 1,
"level": "",
"country": "UNITED KINGDOM",
"countrycode": "GB"
},
"clientip": "211.23.139.189",
"card_identifier": "3bbfcb157e5f44ee8856074baf712ae4"
}
*/
</script>


2. 將 Prime 送回去做首次交易的時候,必須要把一個參數 remember 設成 true ,進行第一次交易

這時候它們回應的 JSON 就會有詳細的 card_secret 

C# Code:

public IActionResult OnPostSave()
{
using (var client = new HttpClient())
{
var primeInfo = JsonConvert.DeserializeObject<CardInfo>(Prime);
var url = "https://sandbox.tappaysdk.com/tpc/payment/pay-by-prime";
client.DefaultRequestHeaders.Add("x-api-key", "partner_key");
client.DefaultRequestHeaders.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json"));//ACCEPT header
var requestBody = new
{
partner_key = "partner_key",
prime = primeInfo.card.prime,
amount = "99",
merchant_id = "userid_CTBC",
details = "Some item",
//這參數要射成 true 才會拿到 card_secret
remember=true,
cardholder = new
{
phone_number = "+886923456789",
name = "王小明",
email = "LittleMing@Wang.com",
zip_code = "100",
address = "台北市天龍區芝麻街1號1樓",
national_id = "A123456789"
}
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(requestBody);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = client.PostAsync(url, content).Result;
var responseString = response.Content.ReadAsStringAsync().Result;
Result = responseString;
Console.WriteLine(responseString);
}
return Page();
}
/* Result with card_secret
{
"status": 0,
"msg": "Success",
"amount": 99,
"acquirer": "TW_CTBC",
"currency": "TWD",
"card_secret": {
"card_token": "6140ed9f274bbff606655a4bdb4e7d87c8c2a27d59fbb8ef4fbb8d0d7d647de0",
"card_key": "db9d633cf5a7d602b695cbcca509244b1d833b4752d9960580c191a6d76454a2"
},
"rec_trade_id": "D20240904GcZQ1f",
"bank_transaction_id": "TP20240904GcZQ1f",
"order_number": "",
"auth_code": "829428",
"card_info": {
"issuer": "",
"funding": 0,
"type": 1,
"level": "",
"country": "UNITED KINGDOM",
"last_four": "4242",
"bin_code": "424242",
"issuer_zh_tw": "",
"bank_id": "",
"country_code": "GB",
"expiry_date": "202902"
},
"transaction_time_millis": 1725421174282,
"bank_transaction_time": {
"start_time_millis": "1725421174325",
"end_time_millis": "1725421174325"
},
"bank_result_code": "",
"bank_result_msg": "",
"card_identifier": "3bbfcb157e5f44ee8856074baf712ae4",
"merchant_id": "no2somdej_CTBC",
"is_rba_verified": false,
"transaction_method_details": {
"transaction_method_reference": "REQUEST",
"transaction_method": "FRICTIONLESS"
}
}
*/


3. 之後就可以透過 card_secret 做之後的消費扣款,不需要客戶再輸入一次卡號

C# Code:

using (var client = new HttpClient())
{
var url = "https://sandbox.tappaysdk.com/tpc/payment/pay-by-token";
client.DefaultRequestHeaders.Add("x-api-key", "partner_key");
client.DefaultRequestHeaders
.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json"));//ACCEPT header
var requestBody = new
{
//from card_secret
card_key= "64575fa115981d67d4eec89df8407e9b024d097a703f9f159aad271387bc8e13",
card_token= "1bd3eefb8d0def18f946623787a19d2ec9c54d527469c64f9f24f05d29ec4ba4",
partner_key = "partner_besc5SvEihVTIGv8UzLRxa53yfmfJ73YnLgQyPUIHOFbrMXMASglg4d6",
amount = "96",
currency="TWD",
merchant_id = "_CTBC",
details = "測試商品_"+DateTime.Now.ToString("yyyy-MM-dd HHMMss"),
remember = true,
cardholder = new
{
phone_number = "+886923456789",
name = "許當麻",
email = "no2somdej@gmail.com",
zip_code = "231",
address = "台北市天龍區芝麻街1號1樓",
national_id = "A123456789"
}
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(requestBody);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = client.PostAsync(url, content).Result;
var responseString = response.Content.ReadAsStringAsync().Result;
Result = responseString;
Console.WriteLine(responseString);
}
/* Result
{
"status": 0,
"msg": "Success",
"amount": 96,
"acquirer": "TW_CTBC",
"currency": "TWD",
"rec_trade_id": "D20240904ojlXMT",
"bank_transaction_id": "TP20240904ojlXMT",
"order_number": "",
"auth_code": "732341",
"card_info": {
"issuer": "",
"funding": 0,
"type": 1,
"level": "",
"country": "UNITED KINGDOM",
"last_four": "4242",
"bin_code": "424242",
"issuer_zh_tw": "",
"bank_id": "",
"country_code": "GB",
"expiry_date": "202704"
},
"transaction_time_millis": 1725426202354,
"bank_transaction_time": {
"start_time_millis": "1725426202410",
"end_time_millis": "1725426202410"
},
"bank_result_code": "",
"bank_result_msg": "",
"card_identifier": "3bbfcb157e5f44ee8856074baf712ae4",
"merchant_id": "no2somdej_CTBC",
"is_rba_verified": false,
"transaction_method_details": {
"transaction_method_reference": "REQUEST",
"transaction_method": "FRICTIONLESS"
}
}
*/


Result:


reference:

https://docs.tappaysdk.com/tutorial/zh/back.html#pay-by-card-token-api

https://blog.no2don.com/2024/09/c-sharp-tabpay-get-prime-ctbc.html



當麻許的超技八 2014 | Donma Hsu Design.