Alipay+ DocsAlipay+ Docs

Sign a request and validate the signature

To ensure message transmission security, the Acquiring Service Provider (ACQP) must properly perform message signing and signature validation:

  • When calling an Alipay+ API, the ACQP must sign the API request and validate the response signature accordingly. For more information, see Direction: ACQP > Alipay+.
  • When receiving an API call from Alipay+, the ACQP must validate the request signature and sign the API response accordingly. For more information, see Direction: Alipay+ > ACQP.

Before you begin

Create your private key and public key pair and obtain the Alipay+ public key through the following steps:

  1. Create an application in Alipay+ Developer Center. For more information, see Create an application.
  2. Create your private key and public key pair with the provided tool, and submit your public key. Obtain the Alipay+ public key, which is generated automatically.
    The keys in the sandbox environment must differ from the ones in the production environment. Therefore, you must get the Alipay+ public keys for the sandbox environment and the production environment separately. For step-by-step instructions, see Set a sandbox public key and Set a production public key separately.

Direction: Acquiring Service Provider > Alipay+

This section introduces the ACQP toAlipay+ API workflow.

Sign a request

The following steps demonstrate how to sign a request message:

1. Create your private key

Create your private key with the provided tool. For more information, see Before you begin.

In this topic, privateKey is used to represent the private key.

2. Construct the content to be signed

Take a request as an example, which includes the following properties:

  • Request-URI: /aps/api/v1/payments/pay
  • Client-Id: SANDBOX_5YC47N2ZQHJ004124
  • Request-Time: 2025-02-20T08:51:49.09Z
  • Request-Body: The following code sample describes the body format. For example:
copy
{
 "order":{
    "orderId":"OrderID_0101010101",
    "orderDescription":"sample_order",
    "orderAmount":{
       "value":"100",
       "currency":"JPY"
    }
 },
 "paymentAmount":{
    "value":"100",
    "currency":"JPY"
 },
 "paymentFactor": {
     "isInStorePayment": "true"
 } 
}

By complying with the Syntax of Content_To_Be_Signed, the content to be signed (Content_To_Be_Signed) is created as follows:

copy
POST /aps/api/v1/payments/pay
SANDBOX_5YC47N2ZQHJ004124.2025-02-20T08:51:49.09Z.{"order":{"orderId":"OrderID_0101010101","orderDescription":"sample_order","orderAmount":{"value":"100","currency":"JPY"}},"paymentAmount":{"value":"100","currency":"JPY"},"paymentFactor":{"isInStorePayment":"true"}}

Syntax of Content_To_Be_Signed

copy
<HTTP-METHOD> <Request-URI>
<Client-Id>.<Request-Time>.<Request-Body>
  • HTTP-METHOD: POST
  • Request-URI: The {endpoint} part of the whole URL https://{host}{endpoint}. For example, if the HTTP URL is https://www.example.com/aps/api/v1/payments/pay, this property is /aps/api/v1/payments/pay.
  • Client-Id: A unique ID that is assigned by Alipay+ to identify a Partner. For example, SANDBOX_5YC47N2ZQHJ004124.
  • Request-Time: Specifies the time when a request is sent, as defined by ISO 8601. This field must be accurate to at least seconds. For example, 2019-05-28T12:12:12+08:00 and 2025-02-20T08:51:49.09Z.
  • Request-Body: The body of the request.

3. Calculate and generate the signature

Use the base64UrlEncode and sha256withrsa methods that involve the proper algorithm and private key to calculate and generate the signature.

copy
generatedSignature=base64UrlEncode(sha256withrsa(<Content_To_Be_Signed>, <privateKey>))

Methods that are used:

  • sha256withrsa: The method to generate a digital signature for the content provided.
  • base64UrlEncode: The method to encode the generated digital signature.

Input parameters:

  • Content_To_Be_Signed: The content to be signed that is obtained in Step 2.
  • privateKey: The private key value that is obtained in Step 1. For example:
copy
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCCI9ml0PnMlZZaMYujB1gzmV9UJG+8aezFRiGaZ7e+yLz94i2sibIHwMDI4UCUNt+kMXHyaTkFRj1PYVunflFk85Hyh+kafsImKvPvuF3gesxJOfWvz3yROo+P+I1hUjmHN00xPwpDAncT5zCjMfAPb/TBDEAXC/GIrC+t0LpcPVARcCP4lI56UjZAd7KzVye7Xldc27O/K3BtJmlaRdn490jlJ1RPC6kS5UZH8d5UGbrjGYv4vz8aCQaTO4ZYQ4yEpE7A2kHHRLpdxL6cNPBEihpa/K3L48zJqXz3OT9AO27T/Hkz8uqBAQFDRHJMrOpOad/0yqUtRtRBAgxi+pTVAgMBAAECggEAFUNuSF2AsyCt1EbMHfMRQj0JCmJ5rztPaFwxGV1g9FcwKftOoyZMZF/mH+xN9OmSWO2LRKRUoLv9QH8TzqYg/nGdoxb5y05ywnG6MazaCdeGkWBa+ELag5Ah7NAbqY8ZvzIV9rnqH1DDzAi2NbPvGVadkv1Ba4KUEFSx5aB5EqDmTgwQ7lisYNVf3tKAbqfY1gTHwi6SI5msURUgQ4e1qbXiQcw15I93WMfm6PKPgbevBMjmqvSKOdo/M3LBXrIyqTm3nExI1itLOi00LxjPtgI/Ke68rcGhdS79ZWeEecXqeotViG+iwOW9YSuOF72MkrgD2l1GT7pMCF+xTdbDgQKBgQC7GuB2wvNz0DWA3GO7HHh8bXavQwDLqV/UW9H2JMYFlAzyVzZNErHVg0Ew9qsESi9Vgz3fH8DnstdoMCjdX+HmvSWnM0IOTtqe6JqRSiCyu03Mkn4HFPRd7myE9GfdSQCWp8mhuVKJTGxK8+Cg2JIxAsEl2JDDlFV9YYPdz4Tp7QKBgQCyD0XHi6hOjiV9WO2jN2zJYgtIsAiDn1Ch1dBahVm9mbay8KrwdR9NrIn73Bh16Hb0I1ObismfEWclYA/Fh1uXKWkFsy3t/BfVIofWYuLUFcOXad8srfyNlPCYRsng7kd2JDfQBoEg1YNxxRZgPsBxLz463cDMV/7sqRYY1N5ZiQKBgE4lT5LKobvBPldvtQe1QG1XmrZgmbh2KVwcbXkMqtgxmaat3jQalsPCajv1CkBka5ifk/vY20zqWSVe1/J91W/1mABZXEF1lcHBDK2Z9EYyDLBgjtqOWfHRXum42piFoQVLVt+A84P8s04qxaroSUbHC7yu0uec0IfpbpX50l2RAoGANFpDNQF98eLfaPRtonCYXrmiAbQoPLLp3TtlcEgG87UvP3t9dweotYjGZTP4SSqZVvzQB0qOL2PJhPayjGxY5J/7Tf65wWA+jZ8Ce2lFsf/YKzuor5VUTTh+aPdfQfAtOLI7asGO092TMS82fgPVRzIRxPMQTcSNon2wjop/+akCgYBAAmFHmEol9wgAOVh70T5A3HP7xXDdBb1bn+g+IR3UgMyji/aHgfOjJdBfrS77cDOb9PXAhMLReiJQWvet7GbkshHiiHrojlDVrUWzPOB4BKbu5LoVyYNUbTsEwebZl2vLkOoFap2CX4Tvhfghg4iMXOpcUKejEVv8T9IsrhQw5g==

With the preceding example Content_To_Be_Signed and privateKey, the generated signature (represented by generatedSignature) is as follows:

copy
HRkD%2Fx8Muwg8yNSS8RUwyBkwfQ1Q2AMvdErhwfZYjkXevMwsXuK0MnA8IE3TWsJv0VRTpcIZrCKZCt2cFmshZUDrdwF91o0kLKdjQXOSycacTWqxoIPhkJXKeEQ4PfeMJ0E4Ag0h0vNMpLceG5nvkeY3I12ErVniKrUkjSBiVC4hAPCUX%2FV2KtYTVerrtIEx%2BjjdHbqvW1SdehKOe9VduXq8b0K5NVDhKCrZfBGj%2F30lYq8SBWCXaDP56dEoXhYsw937ryFln7uKOKRkfJnoKVjUwVB7DUJaVnYJhcMZMzNF4wGk%2FLxc9moSJLQYf7fpjz%2F5lsPcqLYt%2FxN5cMUvFA%3D%3D

4. Configure the signature in the request header

Assemble a signature string by using the following syntax:

copy
'Signature: algorithm=<algorithm>, keyVersion=<key-version>, signature=<generatedSignature>'
  • algorithm , keyVersion: See the header of the chapter Message structure.
  • generatedSignature: The signature that is generated in Step 3.

The following sample describes an assembled signature string:

copy
'Signature: algorithm=RSA256, keyVersion=0, signature=HRkD%2Fx8Muwg8yNSS8RUwyBkwfQ1Q2AMvdErhwfZYjkXevMwsXuK0MnA8IE3TWsJv0VRTpcIZrCKZCt2cFmshZUDrdwF91o0kLKdjQXOSycacTWqxoIPhkJXKeEQ4PfeMJ0E4Ag0h0vNMpLceG5nvkeY3I12ErVniKrUkjSBiVC4hAPCUX%2FV2KtYTVerrtIEx%2BjjdHbqvW1SdehKOe9VduXq8b0K5NVDhKCrZfBGj%2F30lYq8SBWCXaDP56dEoXhYsw937ryFln7uKOKRkfJnoKVjUwVB7DUJaVnYJhcMZMzNF4wGk%2FLxc9moSJLQYf7fpjz%2F5lsPcqLYt%2FxN5cMUvFA%3D%3D'

Then, add the signature string to the request header.

Send a request

Construct a request by adding the Client-Id, Request-Time, and Signature fields to the request header. After a request is constructed, you can use common tools, such as cURL or Postman, to send the request. In the following example, cURL is used:

copy
curl -X POST \
https://example.com/aps/api/v1/payments/pay \
-H 'Content-Type: application/json' \
-H 'Client-Id: SANDBOX_5YC47N2ZQHJ004124' \
-H 'Request-Time: 2025-02-20T08:51:49.09Z' \
-H 'Signature: algorithm=RSA256, keyVersion=0, signature=HRkD%2Fx8Muwg8yNSS8RUwyBkwfQ1Q2AMvdErhwfZYjkXevMwsXuK0MnA8IE3TWsJv0VRTpcIZrCKZCt2cFmshZUDrdwF91o0kLKdjQXOSycacTWqxoIPhkJXKeEQ4PfeMJ0E4Ag0h0vNMpLceG5nvkeY3I12ErVniKrUkjSBiVC4hAPCUX%2FV2KtYTVerrtIEx%2BjjdHbqvW1SdehKOe9VduXq8b0K5NVDhKCrZfBGj%2F30lYq8SBWCXaDP56dEoXhYsw937ryFln7uKOKRkfJnoKVjUwVB7DUJaVnYJhcMZMzNF4wGk%2FLxc9moSJLQYf7fpjz%2F5lsPcqLYt%2FxN5cMUvFA%3D%3D' \
-d '{
  "order":{
    "orderId":"OrderID_0101010101",
    "orderDescription":"sample_order",
    "orderAmount":{
      "value":"100",
      "currency":"JPY"
    }
  },
  "paymentAmount":{
    "value":"100",
    "currency":"JPY"
  },
  "paymentFactor": {
    "isInStorePayment": "true"
  } 
}'

Handle a response

After you receive a response, you need to validate the signature of the response. A response consists of a response header and a response body. The following examples show the header and body of a response:

  • The response header sample
copy
Client-Id: SANDBOX_5YC47N2ZQHJ004124
Response-Time: 2025-02-21T05:43:09Z
Signature: algorithm=RSA256, keyVersion=0, signature=LG8hpLILF1sKlydGaB2cr4EwpG%2BnZiqp1omV6IHgYDeCd6wzA9c2UMNM%2BkxK%2Bltdjers6R6jMxld5%2BuM1MAAO%2F1wHQ%2FVpGeUkGXV%2Fk6Ow7wd%2FjNTLZ%2FB5Cpi9qudkWNXxW3N1eCvcys6wVIHP75A9I4aMX5zBUDjjodVP0gj02F84h%2F0ailuWVMFqEF%2B%2FIHNRT88J5idyrDLlgo%2Fg32d%2BddkFXrcLYhbWi9gSlmG3JtY5Mj9XzS%2FuNt6SkKK%2BT3WdD1q0sbbHtN4reJDNyF%2BABIWlY8Y3Y2OGQbSBcpQZwKep6uG0dAIKAcRgeQtUtpqOUumnolY4LmSr4HRRd15rw%3D%3D

  • The response body sample
copy
{
  "result":{
    "resultCode":"ORDER_NOT_EXIST",
    "resultMessage":"Order does not exist.",
    "resultStatus":"F"
  }
}

The following steps demonstrate how to validate the signature of a response by using the example above.

1. Obtain the Alipay+ public key

Obtain the Alipay+ public key by uploading your public key. For more information, see Before you begin.

2. Construct the content to be validated

Given the response body sample above, construct the content to be validated (Content_To_Be_Validated) by complying with the Syntax of Content_To_Be_Validated as follows:

copy
POST /aps/api/v1/payments/inquiryPayment
SANDBOX_5YC47N2ZQHJ004124.2025-02-21T05:43:09Z.{"result":{"resultCode":"ORDER_NOT_EXIST","resultMessage":"Order does not exist.","resultStatus":"F"}}

Syntax of Content_To_Be_Validated

copy
<HTTP-METHOD> <Response-URI>
<Client-Id>.<Response-Time>.<Response-Body>
  • HTTP-METHOD: POST
  • Response-URI: The URI of an HTTP link. For example, if the URL is https://example.com/aps/api/v1/payments/inquiryPayment, this field is /aps/api/v1/payments/inquiryPayment.
  • Client-Id: A unique ID that is assigned by Alipay+ to identify a Partner. You can get this field from the response header. For example SANDBOX_5YC47N2ZQHJ004124.
  • Response-Time: Specifies the time when a response is returned, as defined by ISO 8601. This field must be accurate to at least seconds. You can get this field from the response header.
  • Response-Body: Specifies the body of the response.

3. Get the signature from the response header

The target signature string ( target_signature ) is extracted from the Signature header of the response. For details about the response header, see the chapter Message structure.

copy
Signature: algorithm=RSA256, keyVersion=0, signature=<target_signature>

4. Validate the signature

Use the sha256withrsa_verify method to validate the signature of the response.

The syntax of the sha256withrsa_verify method is as follows:

copy
IS_SIGNATURE_VALID=sha256withrsa_verify(base64UrlDecode(<target_signature>), <Content_To_Be_Validated>, <serverPublicKey>)

Methods:

  • base64UrlDecode: The method to decode the signature.
  • sha256withrsa_verify: The method to verify the signature.

Input parameters:

  • target_signature: The target signature that is obtained in Step 3.
  • Content_To_Be_Validated: the content to be validated, which is created in Step 2.
  • serverPublicKey: The Alipay+ public key that is obtained in Step 1. For example:
copy
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjCnZV89YE5FpawMMA25JWlwnzKI5r0/F0DH0hBrW3aOLqqqFrYEzN1FzUuv9Gnji8rMU2gkdpsiSfsg/nIIfn3B/ANHO046j9eM2TvvC1Ppi8FEJnh2liKzkQwWDiSPFfeLoR6J8OK0bFrhdr/f/O+PVuowLrZSFMf3rXhxQzvsnoBPsoEqLy8BDwBnagMynpdWuTt8ng2ulsi9CZaJf7ZKXQWJabZKq5E5Qf7ejUWGFwbAAor8Ht7fGWOy2Ayd6s8kBZ6xoJYkyHL08pQamy4tSQ20FVQi/z3DzgfnH+caSIPogzkmfbWjgIvCZ/f+EfuJxq827A+DavJR8/vMEpwIDAQAB

Output parameter:

  • IS_SIGNATURE_VALID: A Boolean value that specifies whether the signature is valid.
    • true: The signature is valid.
    • false: The signature is not valid. Possible causes are that the private key and the public key do not match, or Content_To_Be_Validated is not correctly constructed.

With the preceding example target_signature,Content_To_Be_Validated, and serverPublicKey, the result of IS_SIGNATURE_VALID) is true.

Direction: Alipay+ > Acquiring Service Provider

This section introduces the Alipay+ to ACQP API workflow.

Handle a request

After you receive a request from Alipay+, you need to validate the signature of the request. The process is similar to the process introduced in Handle a response. To validate the signature, complete the following steps:

  1. Obtain the Alipay+ public key, which is used to validate the request signature.
  2. Construct the Content_To_Be_Validated, which is:
copy
<HTTP-METHOD> <Request-URI>
<Client-Id>.<Request-Time>.<Request-Body>

Note: The Request-URI is the endpoint of your API path. For example, when Alipay+ sends a notifyPayment request to the API path https://www.sampleAcquirer.com/aaa/bbb/ccc, the Request-URI is /aaa/bbb/ccc.

  1. Get the signature from the request header.
  2. Validate the signature.

Sign a response

You must sign your response before sending it to Alipay+. The process is similar to the process introduced in Sign a request. To sign your response, complete the following steps:

  1. Obtain your private key to sign the response.
  2. Construct the content to be signed, which is:
copy
<HTTP-METHOD> <Response-URI>
<Client-Id>.<Response-Time>.<Response-Body>
  • HTTP-METHOD: POST
  • Response-URI: The endpoint of your API path. For example, when you respond to Alipay+'s notifyPayment request, whose API path is https://www.sampleAcquirer.com/aaa/bbb/ccc, the Response-URI is /aaa/bbb/ccc.
  • Client-Id: A unique ID that is assigned by Alipay+ to identify a Partner. For example, SANDBOX_5YC47N2ZQHJ004124.
  • Response-Time: Specifies the time when a request is sent, as defined by ISO 8601. This field must be accurate to at least seconds. For example, 2019-05-28T12:12:14+08:00.
  • Response-Body: The body of the response.

For example:

copy
POST /aaa/bbb/ccc
SANDBOX_5YC47N2ZQHJ004124.2019-05-28T12:12:14+08:00.{"result":{"resultCode":"SUCCESS","resultStatus":"S","resultMessage":"success"}}
  1. Calculate and generate the signature.
  2. Configure the signature in the response header.

Send a response

Construct a response by adding the Client-Id, Response-Time, and Signature fields to the response header and send it to Alipay+.

An example of the response that Alipay+ receives is shown as follows. In the following example, cURL is used by Alipay+ to receive the response.

copy
curl -X POST \
  https://www.sampleAcquirer.com/aaa/bbb/ccc \
  -H 'Content-Type: application/json' \
  -H 'Client-Id: SANDBOX_5YC47N2ZQHJ004124' \
  -H 'Response-Time: 2019-05-28T12:12:14+08:00' \
  -H 'Signature: algorithm=RSA256, keyVersion=0, signature=sampleSignature***' \
  -d '{
  "result": {
    "resultCode": "SUCCESS",
    "resultStatus": "S",
    "resultMessage": "success"
  }
}'