Pockyt uses three credentials to authenticate every API call: merchantNo, storeNo, and an API Token. The token is never sent over the wire — instead, it is used to generate a verifySign hash that proves you hold the token.
This same signing mechanism also lets you verify that incoming IPN (Instant Payment Notification) callbacks genuinely came from Pockyt.
Obtaining API Credentials
Sandbox Access
Obtain sandbox credentials by contacting [email protected] or by registering at the Pockyt Sandbox Application.
Production Access
Production credentials are provided after completing the merchant onboarding process.
Credentials Breakdown
| Credential | Description |
|---|---|
merchantNo | A unique number assigned to your merchant account. |
storeNo | A number associated with a specific store under the merchant. Additional store numbers can be created via the Pockyt Merchant Portal. |
API Token | A developer token used to generate verifySign signatures. Never send this token directly in an API request. |
All three credentials are required to sign and verify API calls.
Best Practices for API Token Security
- Secure Storage — Store your API token in a database or backend configuration file. Do not hard-code it into source code or commit it to version control.
- Encryption — Use strong encryption algorithms like AES or RSA to protect stored tokens.
- Rate Limiting — Implement rate limiting to prevent brute force attacks.
- Log Monitoring — Regularly check logs for suspicious activity, such as repeated failed API requests.
Signing API Calls
Pockyt secures API transactions using the verifySign parameter, which authenticates requests without requiring secret tokens or passwords to be transmitted.
How to Generate verifySign
verifySign
Steps for generating the verifySign signature
- Collect all request parameters (excluding
verifySignitself).- Sort the parameters alphabetically by key name.
- Concatenate them in
key=valueformat, joined by&.- Compute the MD5 hash of your API Token and append it to the string, prefixed with
&.- Compute the MD5 hash of the entire concatenated string. This is your
verifySign.
Worked Example
Assume the following request parameters and API token:
API Token: 5cbfb079f15b150122261c8537086d77
Input Parameters:
amount = '1.00'
storeNo = '300014'
currency = 'USD'
settleCurrency = 'USD'
merchantNo = '200043'
callbackUrl = 'https://wx.yuansfer.yunkeguan.com/wx'
terminal = 'ONLINE'
ipnUrl = 'https://wx.yuansfer.yunkeguan.com/wx'
reference = 'seq_1525922323'
vendor = 'alipay'
goodsInfo = '[{"goods_name":"Yuansfer","quantity":"1"}]'
timeout = '120'Step 1 — Sort parameters alphabetically:
amount = '1.00'
callbackUrl = 'https://wx.yuansfer.yunkeguan.com/wx'
currency = 'USD'
goodsInfo = '[{"goods_name":"Yuansfer","quantity":"1"}]'
ipnUrl = 'https://wx.yuansfer.yunkeguan.com/wx'
merchantNo = '200043'
reference = 'seq_1525922323'
settleCurrency = 'USD'
storeNo = '300014'
terminal = 'ONLINE'
timeout = '120'
vendor = 'alipay'Step 2 — Concatenate as key=value&key=value:
amount=1.00&callbackUrl=https://wx.yuansfer.yunkeguan.com/wx¤cy=USD&goodsInfo=[{"goods_name":"Yuansfer","quantity":"1"}]&ipnUrl=https://wx.yuansfer.yunkeguan.com/wx&merchantNo=200043&reference=seq_1525922323&settleCurrency=USD&storeNo=300014&terminal=ONLINE&timeout=120&vendor=alipay
Step 3 — Hash the API Token and append it:
MD5("5cbfb079f15b150122261c8537086d77") = 45ba0f07f3b6d4acb3f3278f629dc9e6
Append with &:
amount=1.00&callbackUrl=https://wx.yuansfer.yunkeguan.com/wx¤cy=USD&goodsInfo=[{"goods_name":"Yuansfer","quantity":"1"}]&ipnUrl=https://wx.yuansfer.yunkeguan.com/wx&merchantNo=200043&reference=seq_1525922323&settleCurrency=USD&storeNo=300014&terminal=ONLINE&timeout=120&vendor=alipay&45ba0f07f3b6d4acb3f3278f629dc9e6
Step 4 — Compute the final MD5 hash:
MD5(concatenated string) = 5876be977662d1b66c88e8df4d0babe7
Your verifySign value is 5876be977662d1b66c88e8df4d0babe7.
Example cURL Request
curl -X POST 'https://mapi.yuansfer.com/online/v3/secure-pay' \
-H "Content-Type: application/json" \
-d '{
"amount": "1.00",
"storeNo": "300014",
"currency": "USD",
"settleCurrency": "USD",
"merchantNo": "200043",
"callbackUrl": "https://wx.yuansfer.yunkeguan.com/wx",
"terminal": "ONLINE",
"ipnUrl": "https://wx.yuansfer.yunkeguan.com/wx",
"reference": "seq_1525922323",
"vendor": "alipay",
"goodsInfo": "[{\"goods_name\":\"Yuansfer\",\"quantity\":\"1\"}]",
"timeout": "120",
"verifySign": "5876be977662d1b66c88e8df4d0babe7"
}'Verifying IPN Webhook Signatures
When a transaction completes, Pockyt sends a POST request to the ipnUrl you provided. This payload includes a verifySign field so you can confirm the request actually came from Pockyt and was not tampered with.
Always verifyverifySignon incoming IPN callbacks. Skipping this step leaves your integration vulnerable to spoofed notifications.
How to Verify
- Extract all fields from the IPN payload except
verifySign. - Follow the exact same signing process described above (sort → concatenate → append MD5 of your API Token → hash).
- Compare the
verifySignyou computed with the one in the payload. If they match, the notification is authentic.
Worked Example
Pockyt sends the following IPN payload to your ipnUrl:
{
"amount": "20.00",
"currency": "USD",
"note": "test note",
"reference": "bIJrcfAwd11sdeddd944cZdZ",
"settleCurrency": "USD",
"status": "success",
"supUserid": "$CASHTAG_C_TOKEN",
"time": "20260410220643",
"transactionNo": "305890742378708206",
"vendorId": "PWC_22wq80e5qy5tar5kkq24h0knd",
"verifySign": "ea1f9ad19f977d5f7d54dca746e2d88b"
}Your API Token: 5cbfb079f15b150122261c8537086d77
Step 1 — Extract all fields except verifySign and sort alphabetically:
amount = '20.00'
currency = 'USD'
note = 'test note'
reference = 'bIJrcfAwd11sdeddd944cZdZ'
settleCurrency = 'USD'
status = 'success'
supUserid = '$CASHTAG_C_TOKEN'
time = '20260410220643'
transactionNo = '305890742378708206'
vendorId = 'PWC_22wq80e5qy5tar5kkq24h0knd'Step 2 — Concatenate:
amount=20.00¤cy=USD¬e=test note&reference=bIJrcfAwd11sdeddd944cZdZ&settleCurrency=USD&status=success&supUserid=$CASHTAG_C_TOKEN&time=20260410220643&transactionNo=305890742378708206&vendorId=PWC_22wq80e5qy5tar5kkq24h0knd
Step 3 — Hash the API Token and append:
MD5("5cbfb079f15b150122261c8537086d77") = 45ba0f07f3b6d4acb3f3278f629dc9e6
Appended string:
amount=20.00¤cy=USD¬e=test note&reference=bIJrcfAwd11sdeddd944cZdZ&settleCurrency=USD&status=success&supUserid=$CASHTAG_C_TOKEN&time=20260410220643&transactionNo=305890742378708206&vendorId=PWC_22wq80e5qy5tar5kkq24h0knd&45ba0f07f3b6d4acb3f3278f629dc9e6
Step 4 — Compute the final MD5:
MD5(concatenated string) = ea1f9ad19f977d5f7d54dca746e2d88b
Step 5 — Compare:
| Value | Hash |
|---|---|
Received verifySign | ea1f9ad19f977d5f7d54dca746e2d88b |
Computed verifySign | ea1f9ad19f977d5f7d54dca746e2d88b |
✅ Match — the IPN notification is authentic. Process the transaction update. If they do not match, reject the request and log it for investigation.
Reference Implementation (Python)
import hashlib
def compute_verify_sign(params: dict, api_token: str) -> str:
"""
Compute the verifySign hash for a set of parameters.
Works for both signing outbound requests and verifying inbound IPNs.
"""
# Remove verifySign if present (for IPN verification)
filtered = {k: v for k, v in params.items() if k != "verifySign"}
# Step 1 & 2: Sort and concatenate
sorted_keys = sorted(filtered.keys())
concatenated = "&".join(f"{k}={filtered[k]}" for k in sorted_keys)
# Step 3: Append MD5 of API token
token_md5 = hashlib.md5(api_token.encode()).hexdigest()
final_string = concatenated + "&" + token_md5
# Step 4: Compute final MD5
return hashlib.md5(final_string.encode()).hexdigest()
def verify_ipn(payload: dict, api_token: str) -> bool:
"""
Verify that an IPN callback is authentic.
Returns True if the verifySign matches, False otherwise.
"""
received_sign = payload.get("verifySign", "")
computed_sign = compute_verify_sign(payload, api_token)
return received_sign == computed_signReference Implementation (Node.js)
const crypto = require("crypto");
function computeVerifySign(params, apiToken) {
// Remove verifySign if present (for IPN verification)
const filtered = Object.fromEntries(
Object.entries(params).filter(([key]) => key !== "verifySign")
);
// Step 1 & 2: Sort and concatenate
const concatenated = Object.keys(filtered)
.sort()
.map((key) => `${key}=${filtered[key]}`)
.join("&");
// Step 3: Append MD5 of API token
const tokenMd5 = crypto.createHash("md5").update(apiToken).digest("hex");
const finalString = `${concatenated}&${tokenMd5}`;
// Step 4: Compute final MD5
return crypto.createHash("md5").update(finalString).digest("hex");
}
function verifyIpn(payload, apiToken) {
const receivedSign = payload.verifySign || "";
const computedSign = computeVerifySign(payload, apiToken);
return receivedSign === computedSign;
}
