iT邦幫忙

2023 iThome 鐵人賽

DAY 21
0
WordPress

透過WordPress架設電商網站,並串接管理後台系列 第 21

«D21»(金流篇)串接 TapPay 金流—Direct Pay - iFrame

  • 分享至 

  • xImage
  •  

官方的 Github 請參考:
https://github.com/TapPay/tappay-web-example/tree/master/Direct_Pay_iframe

為什麼沒辦法直接在 WP 插入 iFrame...?(我也不知道)

這個東東雖然官方有出基本上可以直接無腦放上網頁的 iFrame,但在實際串到 WordPress WooCommerce Checkout Page(結帳頁面)的時候真的是有夠痛苦。
我把官方 Demo Code 拆成 JS 跟其他,JS 使用 enqueue 插到 headers(應該是啦),其他 hook 到 woocommerce_after_checkout_form,暴力插入。
這個是 JS

function custom_enqueue_scripts() {
    // 加入CSS
    wp_enqueue_style('semantic-ui-css', 'https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.13/semantic.min.css');

    // 加入JS
    wp_enqueue_script('jquery');
    wp_enqueue_script('tappay-sdk', 'https://js.tappaysdk.com/sdk/tpdirect/v5.17.0');
    wp_enqueue_script('custom-js', get_stylesheet_directory_uri() . '/js/TapPay_DP.js', array('jquery', 'tappay-sdk'), null, true);
}
add_action('wp_enqueue_scripts', 'custom_enqueue_scripts');

這個是其他

/*TapPay*/
function TapPay_DP_after_payment() {
    ?>
    <!-- Your provided HTML, CSS and JS goes here -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.13/semantic.min.css">
    <style>
        #tappay-iframe {
            font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;
            margin: 0;
            outline: 0;
            -webkit-appearance: none;
            tap-highlight-color: rgba(255,255,255,0);
            line-height: 1.21428571em;
            padding: .578571em 1em;
            font-size: 1em;
            background: #fff;
            border: 1px solid rgba(34,36,38,.15);
            color: rgba(0,0,0,.87);
            border-radius: .28571429rem;
            box-shadow: 0 0 0 0 transparent inset;
            -webkit-transition: color .1s ease,border-color .1s ease;
            transition: color .1s ease,border-color .1s ease;
            width: 100%;
        }
    </style>
    <div class="ui grid centered doubling stackable">
        <div class="six wide column">
            <div class="ui segment">
                <h1 class="ui header">Direct Pay - iframe</h1>

                <form class="ui form">
                    <div class="field">
                        <label>信用卡</label>
                        <div id="tappay-iframe"></div>
                    </div> 
                </form>
                
                <br>
                <!-- 這邊應該要是這樣,而不是原本的:<div class="ui button" id="submit">Get Prime</div> -->
                <button type="button" class="ui button" id="submit" disabled>Get Prime</button>
                <!-- 不然下面的 Javascript 的 if (update.canGetPrime) {submitButton.removeAttribute('disabled')}else{} 會無法作用,因為 disabled 只能用在<button>。我順便把原本的按鈕設定為 disabled,讓使用者在未輸入前就無法使用。 -->
                <!-- 如果你希望這個按鈕可以同時替表單 Submit,你需要確保他跟原本的 place order 按鈕在同個表單下,並且 type="submit",因為一個 form 會聆聽其中的所有 submit -->
                <br>
                <pre class="ui error message" id="message" style="overflow-x: auto">
                </pre>
                <pre class="ui info message" id="result" style="overflow-x: auto">
                </pre>
                <pre class="ui info message" id="curl" style="overflow-x: auto">
                </pre>
            </div>
        </div>
    </div>
    <script>
        var statusTable = {
            '0': '欄位已填好,並且沒有問題',
            '1': '欄位還沒有填寫',
            '2': '欄位有錯誤,此時在 CardView 裡面會用顯示 errorColor',
            '3': '使用者正在輸入中',
        }
        var defaultCardViewStyle = {
            color: 'rgb(0,0,0)',
            fontSize: '15px',
            lineHeight: '24px',
            fontWeight: '300',
            errorColor: 'red',
            placeholderColor: ''
        }
        var config = { 
            isUsedCcv: false,
            // 此設定會顯示卡號輸入正確後,會顯示前六後四碼信用卡卡號
            isMaskCreditCardNumber: true,
            maskCreditCardNumberRange: {
                beginIndex: 6, 
                endIndex: 11
            }
        }
        TPDirect.card.setup('#tappay-iframe', defaultCardViewStyle, config)
        TPDirect.card.onUpdate(function (update) {

            var submitButton = document.querySelector('#submit')
            var cardViewContainer = document.querySelector('#tappay-iframe')

            if (update.canGetPrime) {
                submitButton.removeAttribute('disabled')
            } else {
                submitButton.setAttribute('disabled', true)
            }

            var message = document.querySelector('#message')

            message.innerHTML = `
                canGetPrime: ${update.canGetPrime} \n
                cardNumberStatus: ${statusTable[update.status.number]} \n
                cardExpiryStatus: ${statusTable[update.status.expiry]} \n
                ccvStatus: ${statusTable[update.status.ccv]}
            `.replace(/    /g, '')

            if (update.hasError) {
                message.classList.add('error')
                message.classList.remove('info')
            } else {
                message.classList.remove('error')
                message.classList.add('info')
            }
        })
        document.querySelector('#submit').addEventListener('click', function(event) {
            TPDirect.card.getPrime(function(result) {
                document.querySelector('#result').innerHTML  = JSON.stringify(result, null, 4)

                var command = `
                Use following command to send to server \n\n
                curl -X POST https://sandbox.tappaysdk.com/tpc/payment/pay-by-prime \\
                -H 'content-type: application/json' \\
                -H 'x-api-key: partner_6ID1DoDlaPrfHw6HBZsULfTYtDmWs0q0ZZGKMBpp4YICWBxgK97eK3RM' \\
                -d '{
                    "partner_key": "partner_6ID1DoDlaPrfHw6HBZsULfTYtDmWs0q0ZZGKMBpp4YICWBxgK97eK3RM",
                    "prime": "${result.card.prime}",
                    "amount": "1",
                    "merchant_id": "GlobalTesting_CTBC",
                    "details": "Some item",
                    "cardholder": {
                        "phone_number": "+886923456789",
                        "name": "王小明",
                        "email": "LittleMing@Wang.com",
                        "zip_code": "100",
                        "address": "台北市天龍區芝麻街1號1樓",
                        "national_id": "A123456789"
                    }
                }'`.replace(/                /g, '')

                document.querySelector('#curl').innerHTML = command
            })
        })
    </script>
    <?php
}
add_action('woocommerce_review_order_after_payment', 'TapPay_DP_after_payment');

雖然可以 TPDirect.card.getPrime,但就是會出現 Status 9002

{
    "status": 9002,
    "msg": "Out of range : tappay_sdk_version",
    "card": {},
    "cardinfo": {}
}

https://ithelp.ithome.com.tw/upload/images/20230921/20162937VtWw0dBd74.png
https://ithelp.ithome.com.tw/upload/images/20230921/20162937FqnCymyLWl.png

正常應該長這樣(可以使用 TapPay 的 Demo,)
https://ithelp.ithome.com.tw/upload/images/20230921/20162937rjJunMaOWd.png

找了好久還是沒有解,明天繼續奮鬥!


上一篇
«D20»整理 WooCommerce Webhook 資料
下一篇
«D22»(金流篇)解決 TapPay iFrame 串接 WordPress 出現 9002
系列文
透過WordPress架設電商網站,並串接管理後台30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言