商户接入指南 商户接入指南
  • V2
  • V3 (opens new window)
  • V2
  • V3 (opens new window)
  • 接入指南

    • 起步
    • 名词约定
    • 对接流程(必读)
    • 签名规约
    • 服务端接入流程
    • 3D集成指南V1(From提交)
    • 3D集成指南V2(风控插件)
  • 接入方案

    • 收银台模式

      • 内嵌JS-SDK
      • 跳转接入
        • 收银台模式系统交互流程
        • 请求下单支付
          • 请求地址
          • 请求参数
          • 请求参数签名
          • 加签参数列表
          • 响应参数
          • 重要出参说明
        • 3DS
        • 预授权
          • 什么是预授权
          • 如何发起预授权交易
        • CAPTURE
          • 什么是CAPTURE
          • 如何发起
        • VOID
          • 什么是VOID
          • 如何发起
    • 端到端模式

      • 快速开始
      • 商户收银台规范
    • 交易处理方案

      • 处理交易状态
      • 交易数据处理方案
      • 交易状态处理方案
      • 自动续费场景处理方案
    • 开源建站工具插件支持

      • Magento235
      • Woocommerce
      • OpenCart
      • Prestashop
      • ZenCart
  • APIs

    • 交易下单

      • 收银台模式
      • 端到端模式
      • 退款和预授权
      • 修改交易信息
    • 交易查询

    • 快捷支付

    • 拒付查询

    • 物流信息

    • 交易账单

    • 币种汇率

    • 商户信息

  • 附录

  • v2

跳转接入

# 快速开始

Tips :

推荐使用内嵌接入

由 pingpong checkout 提供收银台⻚面,商户无需自行开发收银台⻚面,执行完结账请求,直接跳转至 pingpong checkout 收银台⻚面。


# 收银台模式系统交互流程

# 如何接入

  • 调用收银台 v2/checkout 接口

  • v2/checkout 接口返回paymentUrl

  • 商户将用户⻚面重定向至 paymentUrl

  • 用户浏览器渲染PingPongPay 收银台⻚面,完成支付


注意 : 在交易进行中,为了更好地帮助商户提前规避风险,若PingPongPay 风控系统识别出订单风险存疑,会在客户端展示交易状态为“status=REVIEW”,PingPongPay将会对订单进行人工审核,商户可以对订单审核结果提出建议。

# 请求下单支付

# 请求地址



https://{host}/v2/checkout
1

# 请求参数


参数必填属性说明:必填(M),可选(O),条件必填(C)。

# 请求参数签名


注意 : 当前接口为部分加签,仅在下面列表中的参数参与签名

# 加签参数列表

参数名 描述
clientId PingPong商户号
accId PingPong商户店铺号
amount 交易金额
currency 交易币种
cardNum 交易卡号
transactionId PingPong交易流水号
merchantTransactionId 商户交易流水号
signType 加签类型
shopperResultUrl 商户自定义接收重定向的结果 URL

# 获取签名参数列表

  1. 准备一个ArrayList 加签参数列表

  2. 遍历收到的请求参数列表。

  3. 每次循环都比较请求参数的参数名是否在加签参数列表

  4. 在加签参数列表的参数加入新的签名参数列表

# PHP伪代码示例:


<?php

$request = isPingPongPay($requestParams);

if(empty($request)){
    throw new Error("验签失败");
}

$needSign = [];

$scope = [
    "clientId",
    "accId",
    "amount",
    "currency",
    "cardNum",
    "transactionId",
    "merchantTransactionId",
    "requestId",
    "signType",
]

foreach($request as $key=>$value){
    if(in_array($key,$scope)){
      $needSign[$key] = $value;   
    }    
 // then if not empty $needSign  you will to Generate signature string  
 
}

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

# 签名串的生成

  1. 待签名参数列表按照字典序排序

  2. 将排序后的待签名参数列表转成url查询字符串(用'=' 进行参数名和参数值(trim 后的值)的拼接,用'&'进行多 个参数之间的拼接,即 key1=val1&key2=val2&key3=val。)

3.拼接签名密钥(secret): 签名密钥放入签名串的位置为签名串的开头,即{salt}key1=val2&key2=val2&key3=val3

  1. 签名串进行MD5运算后所有字符串转成大写,即可获得正确的签名

# 请求示例



    POST /v2/checkout HTTP/1.1
    Host: {host}
    Content-Type: application/json
    Content-Length: 3012
    
    {
        "sign": "3F9DF2F986EFCE55919C2CA991689D4C",
        "signType": "MD5",
        "accId": "2018092714313010016291",
        "amount": "20",
        "currency": "USD",
        "merchantTransactionId": "MTN193495030728",
        "paymentType": "SALE",
        "shopperResultUrl": "http://127.0.0.1:8010/demo/checkoutResult",
        "threeDSecure": "N",
        "riskInfo": {
            "device": {
                "orderTerminal": "01",
                "fingerprintId": "e10adc3949ba59abbe56e057f20f883e"
            },
            "customer": {
                "customerId": "UN00000001",
                "firstName": "James",
                "lastName": "LeBron",
                "email": "demo@pingpongx.com",
                "domain": "pingpongx.com",
                "phone": "15988890852",
                "mobile": "15988890856",
                "workPhone": "15988890852",
                "identificationType": "ID",
                "identificationId": "330102199003070115",
                "registerTime": "20191101122000",
                "registerIp": "222.126.52.23",
                "registerTerminal": "PC",
                "registerCountry": "US",
                "registerRange": "1",
                "orderTime": "20191201122000",
                "orderIp": "222.126.52.23",
                "orderCountry": "US",
                "payIp": "222.126.52.23",
                "payCountry": "US",
                "loginTime": "20200427122000",
                "loginIp": "222.126.52.23",
                "lastPayTime": "20200427122000",
                "acquisitionChannel": "Seach engine",
                "firstOrder": "N",
                "nonMemberOrder": "N",
                "preferentialOrder": "N",
                "birthDate": "20000212",
                "customerStatus": "EXISTING"
            },
            "goods": [
                {
                    "name": "Macaron",
                    "description": "Colorful macaron",
                    "sku": "20191201331",
                    "averageUnitPrice": "20",
                    "number": "1",
                    "virtualProduct": "N"
                }
            ],
            "shipping": {
                "firstName": "James",
                "lastName": "LeBron",
                "phone": "13588185079",
                "email": "demo@pingpognx.com",
                "street": "1986 Broad Street",
                "postcode": "35222",
                "city": "Birmingham",
                "state": "Alabama",
                "country": "US",
                "lastModifierStreetTime": "20191225162010",
                "lastModifierPhoneTime": "20191225162010"
            },
            "billing": {
                "firstName": "James",
                "lastName": "LeBron",
                "phone": "13588185079",
                "email": "demo@pingpognx.com",
                "street": "1986 Broad Street",
                "postcode": "35222",
                "city": "Birmingham",
                "state": "Alabama",
                "country": "US"
            },
            "ecommerce": {
                "freeShipping": "N",
                "shippingMethod": "sea"
            }
        },
        "notificationUrl": "http://127.0.0.1:8010/demo/callback/checkoutCallback",
        "merchantUserId": "UN00000001",
        "remark": "demo-checkout-normal"
    }
    
    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
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    <?php
    
    $curl = curl_init();
    
    curl_setopt_array($curl, array(
      CURLOPT_URL => 'https://%7Bhost%7D/v2/checkout',
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_ENCODING => '',
      CURLOPT_MAXREDIRS => 10,
      CURLOPT_TIMEOUT => 0,
      CURLOPT_FOLLOWLOCATION => true,
      CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
      CURLOPT_CUSTOMREQUEST => 'POST',
      CURLOPT_POSTFIELDS =>'{
        "sign": "3F9DF2F986EFCE55919C2CA991689D4C",
        "signType": "MD5",
        "accId": "2018092714313010016291",
        "amount": "20",
        "currency": "USD",
        "merchantTransactionId": "MTN193495030728",
        "paymentType": "SALE",
        "shopperResultUrl": "http://127.0.0.1:8010/demo/checkoutResult",
        "threeDSecure": "N",
        "riskInfo": {
            "device": {
                "orderTerminal": "01",
                "fingerprintId": "e10adc3949ba59abbe56e057f20f883e"
            },
            "customer": {
                "customerId": "UN00000001",
                "firstName": "James",
                "lastName": "LeBron",
                "email": "demo@pingpongx.com",
                "domain": "pingpongx.com",
                "phone": "15988890852",
                "mobile": "15988890856",
                "workPhone": "15988890852",
                "identificationType": "ID",
                "identificationId": "330102199003070115",
                "registerTime": "20191101122000",
                "registerIp": "222.126.52.23",
                "registerTerminal": "PC",
                "registerCountry": "US",
                "registerRange": "1",
                "orderTime": "20191201122000",
                "orderIp": "222.126.52.23",
                "orderCountry": "US",
                "payIp": "222.126.52.23",
                "payCountry": "US",
                "loginTime": "20200427122000",
                "loginIp": "222.126.52.23",
                "lastPayTime": "20200427122000",
                "acquisitionChannel": "Seach engine",
                "firstOrder": "N",
                "nonMemberOrder": "N",
                "preferentialOrder": "N",
                "birthDate": "20000212",
                "customerStatus": "EXISTING"
            },
            "goods": [
                {
                    "name": "Macaron",
                    "description": "Colorful macaron",
                    "sku": "20191201331",
                    "averageUnitPrice": "20",
                    "number": "1",
                    "virtualProduct": "N"
                }
            ],
            "shipping": {
                "firstName": "James",
                "lastName": "LeBron",
                "phone": "13588185079",
                "email": "demo@pingpognx.com",
                "street": "1986 Broad Street",
                "postcode": "35222",
                "city": "Birmingham",
                "state": "Alabama",
                "country": "US",
                "lastModifierStreetTime": "20191225162010",
                "lastModifierPhoneTime": "20191225162010"
            },
            "billing": {
                "firstName": "James",
                "lastName": "LeBron",
                "phone": "13588185079",
                "email": "demo@pingpognx.com",
                "street": "1986 Broad Street",
                "postcode": "35222",
                "city": "Birmingham",
                "state": "Alabama",
                "country": "US"
            },
            "ecommerce": {
                "freeShipping": "N",
                "shippingMethod": "sea"
            }
        },
        "notificationUrl": "http://127.0.0.1:8010/demo/callback/checkoutCallback",
        "merchantUserId": "UN00000001",
        "remark": "demo-checkout-normal"
    }',
      CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json'
      ),
    ));
    
    $response = curl_exec($curl);
    
    curl_close($curl);
    echo $response;
    
    
    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
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
      OkHttpClient client = new OkHttpClient().newBuilder()
      .build();
    MediaType mediaType = MediaType.parse("application/json");
    RequestBody body = RequestBody.create(mediaType, "{\n    \"sign\": \"3F9DF2F986EFCE55919C2CA991689D4C\",\n    \"signType\": \"MD5\",\n    \"accId\": \"2018092714313010016291\",\n    \"amount\": \"20\",\n    \"currency\": \"USD\",\n    \"merchantTransactionId\": \"MTN193495030728\",\n    \"paymentType\": \"SALE\",\n    \"shopperResultUrl\": \"http://127.0.0.1:8010/demo/checkoutResult\",\n    \"threeDSecure\": \"N\",\n    \"riskInfo\": {\n        \"device\": {\n            \"orderTerminal\": \"01\",\n            \"fingerprintId\": \"e10adc3949ba59abbe56e057f20f883e\"\n        },\n        \"customer\": {\n            \"customerId\": \"UN00000001\",\n            \"firstName\": \"James\",\n            \"lastName\": \"LeBron\",\n            \"email\": \"demo@pingpongx.com\",\n            \"domain\": \"pingpongx.com\",\n            \"phone\": \"15988890852\",\n            \"mobile\": \"15988890856\",\n            \"workPhone\": \"15988890852\",\n            \"identificationType\": \"ID\",\n            \"identificationId\": \"330102199003070115\",\n            \"registerTime\": \"20191101122000\",\n            \"registerIp\": \"222.126.52.23\",\n            \"registerTerminal\": \"PC\",\n            \"registerCountry\": \"US\",\n            \"registerRange\": \"1\",\n            \"orderTime\": \"20191201122000\",\n            \"orderIp\": \"222.126.52.23\",\n            \"orderCountry\": \"US\",\n            \"payIp\": \"222.126.52.23\",\n            \"payCountry\": \"US\",\n            \"loginTime\": \"20200427122000\",\n            \"loginIp\": \"222.126.52.23\",\n            \"lastPayTime\": \"20200427122000\",\n            \"acquisitionChannel\": \"Seach engine\",\n            \"firstOrder\": \"N\",\n            \"nonMemberOrder\": \"N\",\n            \"preferentialOrder\": \"N\",\n            \"birthDate\": \"20000212\",\n            \"customerStatus\": \"EXISTING\"\n        },\n        \"goods\": [\n            {\n                \"name\": \"Macaron\",\n                \"description\": \"Colorful macaron\",\n                \"sku\": \"20191201331\",\n                \"averageUnitPrice\": \"20\",\n                \"number\": \"1\",\n                \"virtualProduct\": \"N\"\n            }\n        ],\n        \"shipping\": {\n            \"firstName\": \"James\",\n            \"lastName\": \"LeBron\",\n            \"phone\": \"13588185079\",\n            \"email\": \"demo@pingpognx.com\",\n            \"street\": \"1986 Broad Street\",\n            \"postcode\": \"35222\",\n            \"city\": \"Birmingham\",\n            \"state\": \"Alabama\",\n            \"country\": \"US\",\n            \"lastModifierStreetTime\": \"20191225162010\",\n            \"lastModifierPhoneTime\": \"20191225162010\"\n        },\n        \"billing\": {\n            \"firstName\": \"James\",\n            \"lastName\": \"LeBron\",\n            \"phone\": \"13588185079\",\n            \"email\": \"demo@pingpognx.com\",\n            \"street\": \"1986 Broad Street\",\n            \"postcode\": \"35222\",\n            \"city\": \"Birmingham\",\n            \"state\": \"Alabama\",\n            \"country\": \"US\"\n        },\n        \"ecommerce\": {\n            \"freeShipping\": \"N\",\n            \"shippingMethod\": \"sea\"\n        }\n    },\n    \"notificationUrl\": \"http://127.0.0.1:8010/demo/callback/checkoutCallback\",\n    \"merchantUserId\": \"UN00000001\",\n    \"remark\": \"demo-checkout-normal\"\n}");
    Request request = new Request.Builder()
      .url("https://{host}/v2/checkout")
      .method("POST", body)
      .addHeader("Content-Type", "application/json")
      .build();
    Response response = client.newCall(request).execute();
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // Make sure to add code blocks to your code group

    # 签名串示例

    signContent:accId=2018092714313010016291&amount=20&currency=USD&merchantTransactionId=MTN193495030728&notificationUrl=http://127.0.0.1:8010/demo/callback/checkoutCallback&shopperResultUrl=http://127.0.0.1:8010/demo/checkoutResult&signType=MD5
    
    1

    # 重要入参说明


    注意 :

    1. merchantTransactionId 应是全局唯一,不可重复

    2. amount 精确到两位小数,没有小数部分的补零。(如 25.12 或 20.00)

    3. paymentType 一般为SALE 如果要对接AUTH请在对接过程告知,并在测试报告中声明,一定通过验收后才能上线,以免发生交易问题

    4. 在收银台模式下 device browserInfo 可以自动抓取,可以不传

    5. shipping billing goods 不能为空 eCommerce airline reCharge carRental 根据行业情况填写,这些参数影响交易成功率,请详实填写。

    6. shipping billing state 美国加拿大地区必须填写二字简码,有些地区没有state,可以填写空字符串。

    7. merchantUserId 必须全局唯一 没登录或者获取不到的情况请传空字符串。



    # 响应参数

    参数字段 参数属性 参数说明
    clientId M PingPong 商户商户号
    accId M PingPong 商户店铺编号
    merchantTransactionId M 商户网站的的交易流水号
    code M 结果状态码
    description M 结果描述
    token M 收银台模式下,本次结账请求的唯一标示
    paymentUrl M PingPong 支付收银台地址
    innerJsUrl M PingPong 内嵌 JS 文件内容地址
    signType M 签名规约,支持 MD5、SHA256,具体⻅本文“签名规约” 一栏
    sign M 签名内容,具体⻅本文“签名规约”一栏
    remark O 商户扩展字段
    paymentHtml O 预留字段

    # 响应示例

    {
        "accId": "2018092714313010016291",
        "clientId": "2018092714313010016",
        "code": "001000",
        "description": "Successful request",
        "innerJsUrl": "https://pay-cdn.pingpongx.com/production/static/sdk/ppPay.min.js?token=vr_YVR8u7rn7C1gG97DOg5W0OxzazxNYIE56ShWjA4lJrY4wchTnb47oNmp-9ubP",
        "merchantTransactionId": "MTN193495030728",
        "paymentUrl": "https://sandbox-pay-checkout.pingpongx.com/index.html?token=vr_YVR8u7rn7C1gG97DOg5W0OxzazxNYIE56ShWjA4lJrY4wchTnb47oNmp-9ubP",
        "sign": "06D1C606847FD77CC70AAEB94A2A40D6",
        "signType": "MD5",
        "token": "vr_YVR8u7rn7C1gG97DOg5W0OxzazxNYIE56ShWjA4lJrY4wchTnb47oNmp-9ubP"
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    # 响应加签串示例

    signContent:accId=2018092714313010016291&clientId=2018092714313010016&code=001000&description=Successful request&innerJsUrl=https://pay-cdn.pingpongx.com/production/static/sdk/ppPay.min.js?token=vr_YVR8u7rn7C1gG97DOg5W0OxzazxNYIE56ShWjA4lJrY4wchTnb47oNmp-9ubP&merchantTransactionId=MTN193495030728&paymentUrl=https://sandbox-pay-checkout.pingpongx.com/index.html?token=vr_YVR8u7rn7C1gG97DOg5W0OxzazxNYIE56ShWjA4lJrY4wchTnb47oNmp-9ubP&signType=MD5&token=vr_YVR8u7rn7C1gG97DOg5W0OxzazxNYIE56ShWjA4lJrY4wchTnb47oNmp-9ubP
    
    1

    # 重要出参说明


    Tips :

    根据是否能够取到token或者paymentUrl来判断是否成功

    响应字段paymentUrl为跳转收银台地址

    # 3DS

    收银台模式下,3DS 流程由 pingpong checkout 进行了内部封装,无需商户额外接入。

    # 预授权

    # 什么是预授权

    • 商户在持卡人消费前先冻结持卡人creditcard的余额或者额度。
    • 持卡人消费结束后,商户再正式扣掉这部分资金,常用于酒店住宿、出租等行业。
    • 线上交易正常预授权资金冻结期限为7天,部分发卡行是30天。

    注意 :
    • PingPongPay默认不会自动解冻持卡人资金。
    • 预授权交易7天或者30天后,如果商户在这期间没有任何操作,发卡行会自动解冻持卡人冻结的资金。
    • 商户发起Auth之后必须发起在恰当时间(通常为7天)发起CAPTURE,否则交易将被超时取消

    # 如何发起预授权交易

    v2/checkout 接口中

    交易类型:

    • SALE-直接付款
    • AUTH-预授权

    填入paymentType= AUTH 即视为AUTH 业务

    # CAPTURE

    # 什么是CAPTURE

    对已经预授权成功的交易,在资金冻结期限内使用预授权完成进行请款操作。

    # 业务前提

    针对“预授权”交易可以发起“预授权完成”操作。

    # 业务限制

    1. 当前“预授权”交易未被判定为“预授权取消”。
    2. 预授权完成的金额需小于等于关联的 CAPTURE 交易。

    # 如何发起

    收银台模式和端到端模式都请求二次交易接口,填入paymentType=CAPTURE发起退款

    # 接口地址

    https://{host}/v2/payment/{transactionId}
    
    1

    参数详见 退款预授权

    # VOID

    # 什么是VOID

    对已经预授权的交易,通知发卡行进行预授权撤销,预授权撤销成功后发卡行会解冻持卡人冻结的资金。

    # 业务前提

    针对“预授权”交易可以发起“预授权撤销”操作。

    # 业务限制

    1. 当前“预授权”交易未被判定为“预授权完成”。
    2. 预授权撤销只能全额撤销。

    # 如何发起

    收银台模式和端到端模式都请求二次交易接口,填入paymentType=VOID发起退款

    # 接口地址

    https://{host}/v2/payment/{transactionId}
    
    1

    参数详见退款预授权

    上次更新: 2024/01/12, 17:42:45
    内嵌JS-SDK
    快速开始

    ← 内嵌JS-SDK 快速开始→

    杭州乒乓智能技术有限公司 | Copyright © 2015-2024 All rights reserved. pay.pingpongx.com
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式