[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>  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.