接入指南 接入指南
  • V2 (opens new window)
  • V3 (opens new window)
  • V4-English (opens new window)
  • V4-经典版 (opens new window)
  • 接入指南
    • 接入准备
    • 快速启动
    • 开发指南
    • 接入方式
    • 工具
    • 附录
    • 术语
  • API文档
    • checkout
    • dispute
    • Tokenization
    • 异步通知
    • Marketplaces
    • Terminal integration API
  • Marketplaces
  • Accept in-person payments with Terminal
  • 覆盖国家
  • 风险管理
  • 对账服务
  • 支付方式
  • V2 (opens new window)
  • V3 (opens new window)
  • V4-English (opens new window)
  • V4-经典版 (opens new window)
  • 接入方式

    • 概览
    • 无代码接入

      • 使用SaaS服务接入
      • 插件接入
      • 支付链
    • 开发者接入

      • PingPong 收银台

        • 概览
        • 内嵌SDK(方案一)
        • OnepageSDK
          • 1. 获取 sdkAccessToken 接口
          • 2. 引入Javascript-SDK
          • 使用示例:
          • 常见问题
        • Elements SDK
        • 跳转收银台
      • Direct API

        • 国际信用卡支付
        • 本地支付
  • v4

OnepageSDK(下单并支付)

加载中...
流程图

# 接入流程

# 1. 获取 sdkAccessToken 接口

商户后端系统通过获取 sdkAccessToken 接口 得到JS-SDK访问凭证(token),该凭证用于前端JS-SDK的初始化调用。

# 2. 引入Javascript-SDK

复制以下代码,通过CDN地址引入 PingPongCheckout Javascript-SDK


    <script type="module" src="https://payssr-cdn.pingpongx.com/production-fra/acquirer-checkout-onepage/sandbox/pp-checkout.js"></script>
    
    1
    <script type="module" src="https://payssr-cdn.pingpongx.com/production-fra/acquirer-checkout-onepage/pp-checkout.js"></script>
    
    1
    <script type="module" src="https://acquirer-cdn.pingpongx.com/acquirer/checkout-onepage/production-sg/pp-checkout.js"></script>
    
    1
    <script type="module" src="https://acquirer-cdn.pingpongx.com/acquirer/checkout-onepage/production-us/pp-checkout.js"></script>
    
    1
    // Make sure to add code blocks to your code group

    # 3. 初始化收银台

    将 pp-checkout 标签插入 html body 中

    <pp-checkout locale="en"></pp-checkout>
    
    1

    调用 PingPong.Checkout.create 完成初始化

    # 入参

    字段 类型 必填 描述 备注
    amount String M 交易金额 该交易仅用于收银台展示,后续金额变更需调用 updateCheckoutHook 函数进行更新
    currency String M 交易币种
    tradeCountry String M 用于指定pingpong收银台国家 后续国家变更需调用 updateCheckoutHook 函数进行更新
    sdkAccessToken String M JS-SDK访问凭证
    originalPay Boolean O 控制是否使用默认的 PingPong 支付按钮 默认为true,若将其设置为false,则表示不使用内置支付按钮。

    此时,需要在页面内自定义支付按钮点击事件中调用 PingPong.Checkout.pay.run() 方法来触发支付流程。
    paymentMethods String[] O 指定支付方式列表,内嵌收银台会根据指定的支付方式进行展示 传入的支付方式将与该accId下配置的支付方式进行交集运算。

    支付方式的展示顺序将根据传入数组的顺序进行排列。
    useTabMode Boolean O 控制是否展示支付方式选项框 默认为true,当设置为false时,如果商户仅有卡支付配置,将不展示选项框,直接显示支付表单。适用于简化用户体验的场景。
    goods Array O 商品列表 同下单接口的 goods 参数,包含 description、imgUrl、name、number、sku、unitPrice、virtualProduct 等字段
    bizType String C ApplePay 绑卡业务参数 ApplePay 交易必传
    固定值: CodeGrant
    recurringInfoDTO Object C 配置 Recurring 付款 ApplePay 交易必传
        recurringPaymentStartDate Date C 首次付款日期 eg: "2024-06-01 00:00:00"
        recurringPaymentIntervalUnit String C 表示年、月、日、时等日历单位的类型 enum: year/month/day/hour/minute
    eg: "month"
        recurringPaymentIntervalCount String C 构成总支付间隔的间隔单位数 eg: "6"
        recurringPaymentEndDate Date C 最后付款日期 eg: "2024-12-01 00:00:00"
      PingPong.Checkout.create({
          amount: '1.08',
          currency: 'USD',
          tradeCountry: 'US',
          originalPay: true,
          useTabMode: false,
          sdkAccessToken: sdkAccessToken,
          paymentMethods: ['VISA', 'Klarna'],
          goods: [{
              description: 'short legs',
              imgUrl: 'http://pic.bizhi360.com/bpic/30/5230.jpg',
              name: '한국어/English',
              number: '1',
              sku: '20230524001',
              unitPrice: '1',
              virtualProduct: 'N'
          }],
          // 如果需走 ApplePay 支付, 需额外传入以下参数
          bizType: 'CodeGrant',
          recurringInfoDTO:{
              recurringPaymentStartDate: "2024-06-01 00:00:00",
              recurringPaymentIntervalUnit: "month",
              recurringPaymentIntervalCount: "6",
              recurringPaymentEndDate: "2024-12-01 00:00:00"
          },
      })
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      // Make sure to add code blocks to your code group

      # 自定义支付按钮(可选)

      用户可以自定义按钮,通过点击事件去绑定 pingpong 的支付功能。

         // 初始化参数中 originalPay 为 false 时, 需自定义支付按钮点击事件
                document.querySelector('#pay').onclick = function () {
                  PingPong.Checkout.pay.run()
                }
        
        1
        2
        3
        4
        // Make sure to add code blocks to your code group

        # 事件监听(可选)

        SDK 支持监听初始化过程中的 ready 和 error 事件,方便外部进行状态管理和错误处理。

           // 监听初始化成功事件
          document.querySelector('pp-checkout').addEventListener('ready', (e) => {
              console.log('SDK初始化成功');
              // 可以在此处执行初始化完成后的逻辑
          });
          
          // 监听初始化失败事件
          document.querySelector('pp-checkout').addEventListener('error', (e) => {
              console.log('SDK初始化失败', e.detail);
              // 可以在此处执行错误处理逻辑,如显示错误提示、重试等
          });
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          // Make sure to add code blocks to your code group

          事件说明:

          1. ready: 当 SDK 初始化成功时触发,表示收银台已准备就绪
          2. error: 当 SDK 初始化失败时触发,事件详情包含在 e.detail 中

          # 4. 修改金额、国家和商品

          在使用全局变量前,请确保Javascript-SDK 加载完成。

          # updateCheckoutHook(可选)

          updateCheckoutHook 用来更新收银台要素。

          # ts 类型
            PingPong.Checkout.updateCheckoutHook: ({amount?: string, tradeCountry?: string, goods?: Goods[]}) => void
            
            1
            // Make sure to add code blocks to your code group

            使用场景:

            1. 当用户选择优惠券后,调用该Hook,传入最新的金额,PP 内嵌收银台会显示最新金额
            PingPong.Checkout.updateCheckoutHook({ amount: newAmount });
            
            1
            1. 当用户选择Country后,调用该Hook,传入最新的Country 二字码,PP 内嵌收银台会根据新的Country渲染支付方式列表
            PingPong.Checkout.updateCheckoutHook({ tradeCountry: newCountry });
            
            1
            1. 当商品信息变更时,调用该Hook,传入最新的 goods,PP 内嵌收银台会显示最新的商品信息
            PingPong.Checkout.updateCheckoutHook({ goods: newGoods });
            
            1

            # 5. 下单前检验

            # beforeCheckoutHook(可选)

            type:

              (() => void) | (() => Promise<void>)
              
              1
              // Make sure to add code blocks to your code group

              beforeCheckoutHook 用来设置发起支付请求前的钩子函数。

              当你在用户点击支付按钮,发起支付请求前,需要执行你自己的业务逻辑,如:上报埋点、检查库存等,可以设置该钩子函数。

              该函数可以返回一个Promise,后续的支付流程会等待该 Promise 状态变为 Fulfilled 后才会继续执行。如果你想在 Promise 状态为 Rejected 或者异步结果不满足你的业务条件时,可以抛出异常,SDK在捕获到异常后中断支付流程。

                PingPong.Checkout.beforeCheckoutHook = async ({payMethod}) => {
                    return fetch('/api/requestInventory').then(res => {
                
                        const { inventoryQuantity } = res;
                
                        if(inventoryQuantity <  MIN_QUANTITY) {
                            throw new Error('库存不足,需中断交易')
                        }
                    }).catch((error) => {
                        throw new Error('接口异常,需中断交易')
                    })
                };
                
                1
                2
                3
                4
                5
                6
                7
                8
                9
                10
                11
                12
                // Make sure to add code blocks to your code group
                # ts 类型
                  PingPong.Checkout.beforeCheckoutHook: (params: {payMethod?: string}) => string | Promise<string>
                  
                  1
                  // Make sure to add code blocks to your code group

                  # 6. 下单

                  点击支付按钮后,调用下单接口支付去完成支付

                  # 7. 错误处理

                  # checkoutFailedHook(可选)

                  type:

                    (() => void) | (() => Promise<void>)
                    
                    1
                    // Make sure to add code blocks to your code group

                    checkoutFailedHook 接收以下参数:

                      (code: string, message: string) => void | Promise<void>;
                      
                      // code: string - 错误码
                      // message: string - 错误消息
                      
                      1
                      2
                      3
                      4
                      // Make sure to add code blocks to your code group

                      checkoutFailedHook 用来自定义错误逻辑

                      当用户支付失败时,PingPong 默认会弹窗提示用户失败原因。如果你想自定义弹窗 UI 或文本,可以设置该钩子函数。

                      该函数可以返回一个 Promise。如果返回 Promise,后续的流程会等待该 Promise 状态变为 Fulfilled 后才继续执行

                        PingPong.Checkout.checkoutFailedHook = (code: string, message: string) => {
                            notification.open({
                                message: 'Error title',
                                description: `${code}: ${message}`
                            })
                        };
                        
                        1
                        2
                        3
                        4
                        5
                        6
                        // Make sure to add code blocks to your code group

                        # 使用示例:

                          <body>
                              <div class="checkout">
                                <!-- billing 表单 -->
                                <form action="/billing"></form>
                                <!-- PingPong 内嵌收银台 -->
                                <pp-checkout locale="en"></pp-checkout>
                                <!-- shipping 表单 -->
                                <form action="/shipping"></form>
                              </div>
                              <div class="pay">
                                <!-- 优惠券码 -->
                                <div class="gift-card"></div>
                                <!-- 自定义支付按钮 -->
                                <button id="customPay">Pay Now</button>
                              </div>
                          
                              <!-- 加载 PingPong JS-SDK -->
                              <script src="https://pay-cdn.pingpongx.com/production-fra/static/
                              pp-checkout-one-page/sandbox/pp-checkout.js"></script>
                          
                              <script>
                                // 3. 初始化
                                const createCheckout = async () => {
                                  PingPong.Checkout.create({
                                    amount: '1.08',
                                    currency: 'USD',
                                    tradeCountry: 'US',
                                    originalPay: false,
                                    sdkAccessToken
                                  })
                                }
                          
                                // 定义hook
                                const createCheckoutHook = () => {
                                  // 5. 定义 beforeCheckoutHook
                                  PingPong.Checkout.beforeCheckoutHook = async ({payMethod}) => this.prePay();
                          
                                  // 7. 定义 checkoutFailedHook
                                  PingPong.Checkout.checkoutFailedHook = (code, message) => {
                                    notification.open({
                                      message: 'Error title',
                                      description: `${code}: ${message}`
                                    })
                                  };
                          
                                  // 4 监听 country、amount
                                  amountEle.addEventListener('input', function() {
                                    const newAmount = event.target.value;
                                    PingPong.Checkout.updateCheckoutHook({amount: newAmount})
                                  });
                          
                                  countryEle.addEventListener('change', function() {
                                    const newCountry = event.target.value;
                                    PingPong.Checkout.updateCheckoutHook({tradeCountry: newCountry})
                                  });
                          
                                  // 初始化参数中 originalPay 为 false 时, 需自定义支付按钮点击事件
                                  document.querySelector('#pay').onclick = function () {
                                    PingPong.Checkout.pay.run()
                                  }
                                }
                          
                                window.onload = function() {
                                  createCheckout();
                                  createCheckoutHook();
                                };
                              </script>
                          </body>
                          </html>
                          
                          1
                          2
                          3
                          4
                          5
                          6
                          7
                          8
                          9
                          10
                          11
                          12
                          13
                          14
                          15
                          16
                          17
                          18
                          19
                          20
                          21
                          22
                          23
                          24
                          25
                          26
                          27
                          28
                          29
                          30
                          31
                          32
                          33
                          34
                          35
                          36
                          37
                          38
                          39
                          40
                          41
                          42
                          43
                          44
                          45
                          46
                          47
                          48
                          49
                          50
                          51
                          52
                          53
                          54
                          55
                          56
                          57
                          58
                          59
                          60
                          61
                          62
                          63
                          64
                          65
                          66
                          67
                          68
                          69
                          // Make sure to add code blocks to your code group

                          # 常见问题

                          # Q1: 为什么我的结账流程无法启动,系统提示 beforeCheckoutHook 相关错误?

                          A: 当系统提示 "The beforeCheckoutHook is not defined or is not a function" 时,表明您的 one-page sdk 配置中缺少有效的 beforeCheckoutHook 函数。请确保在配置中正确定义此函数,它是启动结账流程的必要条件。

                          # Q2: 我已定义 beforeCheckoutHook 函数,但仍收到 token 相关错误,如何解决?

                          A: 错误 "Invalid or missing token returned by beforeCheckoutHook" 表明您的 beforeCheckoutHook 函数未返回有效的 token。请确保该函数返回一个非空字符串类型的 token,这是支付处理的必要凭证。

                          # Q3: 创建支付时,系统提示 amount 参数错误,应如何处理?

                          A: 当系统显示 "Invalid or missing amount: must be a non-empty string" 时,表明您提供的 amount 参数不符合要求。请确保 amount 参数是非空字符串类型,例如 "10.99"。

                          # Q4: 如何确保我使用的货币代码有效?

                          A: 系统支持特定的货币代码列表。如果收到 "Invalid or missing currency" 错误,请检查您提供的货币代码是否在支持列表中。常用的代码包括 "USD"、"EUR"、"CNY" 等。完整列表请参考 API 文档。

                          # Q5: sdkAccessToken 验证失败的原因是什么?

                          A: 错误 "Invalid or missing sdkAccessToken" 表明您提供的 sdkAccessToken 无效或缺失。请确保提供一个有效的、非空字符串类型的 sdkAccessToken,这是身份验证的关键凭证。

                          # Q6: 配置 paymentMethods 时需要注意什么?

                          A: 如果您选择配置 paymentMethods 参数,必须确保它是数组类型。若收到 "Invalid paymentMethods: must be an array or undefined" 错误,请检查您提供的值是否为数组,或考虑完全移除此参数以使用默认支付方式。

                          # Q7: 如何确保 one-page sdk 配置的正确性?

                          A: 建议在实施前全面测试您的配置。特别注意:

                          • beforeCheckoutHook 函数必须正确定义并返回有效 token
                          • 所有必需参数(amount、currency、sdkAccessToken)必须符合类型要求
                          • 可选参数如 paymentMethods 必须符合预期格式

                          # Q8: 支付流程中断时如何快速排查问题?

                          A: 请检查控制台错误信息,它通常会精确指出问题所在。根据错误信息对照本 FAQ 进行相应调整。如果问题持续,请确保您使用的是最新版本的 SDK,并查阅完整的技术文档。

                          上次更新: 2026/01/26, 16:17:49

                          Previous
                          ← 内嵌SDK(方案一)
                          Next
                          Elements SDK→

                          杭州乒乓智能技术有限公司 | Copyright © 2015-2026 checkout.pingpongx.com.All Rights Reserved.
                          • 浅色模式