Security
How to make safe payment requests.
Last updated
Was this helpful?
How to make safe payment requests.
Last updated
Was this helpful?
The signature should use SHA256 as HMAC hash function.
Header
Type
Description
Content-Type
string
application/json; charset=UTF-8
AppId
string
Your App ID in payout platform
Authorization
string
SHA256($sorted_params + $app_key)
Find $AppId, $app_key from the merchant dashboard.
Ascendingly, sorted request params, check below;
Concatenate sorted_params with app_key.
Use sha256(sorted_params + app_key) to get the Authorization.
When sorting parameters, strip the ones with no value.
Letters in Authorization need to be lower case.
package com.pagsmile.ts;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.TreeMap;
public static String getSign(Map<String, String> params, String authKey) {
String param = sortParam(params) + authKey;
return sha256(param);
}
public static String sha256(String str) {
String encodeStr = "";
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] encodedhash = digest.digest(str.getBytes(StandardCharsets.UTF_8));
encodeStr = bytesToHex(encodedhash);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("algorithm not supported");
}
return encodeStr;
}
public static String sortParam(Map<String, String> params) {
try {
Map<String, String> map = new TreeMap<>(params);
StringBuilder sb = new StringBuilder();
for (String k : map.keySet()) {
String v = map.get(k);
if (v != null && v.length() > 0) {
sb.append(k).append("=").append(v).append("&");
}
}
if (sb.length() <= 0) {
return "";
}
return sb.subSequence(0, sb.length() - 1).toString();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
private static String bytesToHex(byte[] hash) {
StringBuilder hexString = new StringBuilder(2 * hash.length);
for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
<?php
public function sign($params = array(),$merchantKey){
ksort($params);
$sign_string = '';
foreach ($params as $key = > $value){
if (!empty($value)){
$sign_string.= $key.'='.$value.'&';
}
}
$sign_string = substr($sign_string, 0, -1);
$sign = hash("sha256", $sign_string.$merchantKey);
return $sign;
}
?>
package crypto
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"sort"
"strings"
)
// signature based sha256
func GetSign(m map[string]interface{}, merchantKey string) string {
var w = sha256.New()
_, _ = io.WriteString(w, sortedAndBuild(m) + merchantKey)
return fmt.Sprintf("%x", w.Sum(nil))
}
func sortedAndBuild(m map[string]interface{}) string {
var b strings.Builder
l, c := len(m), 0
keySet := make([]string, 0, l)
for k, v := range m {
keySet = append(keySet, k)
if _, ok := v.(string); ok {
c = len(k) + len(v.(string)) + 2
} else {
c = len(k) + 10 + 2
}
}
b.Grow(c)
sort.Strings(keySet)
for _, k := range keySet {
if v, ok := m[k]; ok {
var str string
if s, okk := v.(string); okk {
str = s
} else if d, okkk := v.(decimal.Decimal); okkk {
str = d.String()
} else {
str = fmt.Sprintf("%v", v)
}
if len(str) > 0 {
b.WriteString(k)
b.WriteString("=")
b.WriteString(str)
b.WriteString("&")
}
}
}
r := strings.TrimRight(b.String(), "&")
return r
}
# encoding: utf-8
import hashlib
# d is param dict
def ksort(d):
return [(k,d[k]) for k in sorted(d.keys())]
# sha256
def sign(params,merchantKey):
params = ksort(params)
queryStr = ''
for key, value in params:
if value :
queryStr += key + '=' + str(value) + '&'
h2 = hashlib.sha256()
h2.update((queryStr.rstrip('&') + merchantKey).encode(encoding='UTF-8', errors='strict'))
Sample request:
{
"account_digit": "4",
"account_number": "1234567",
"account_type": "CHECKING",
"additional_remark": "1234567_test",
"amount": "10.00",
"bankcode": "001",
"branch": "0001",
"custom_code": "1234567",
"document_id": "50284414727",
"document_type": "CPF",
"fee": "merchant",
"name": "Test User Name",
"notify_url": "https://www.pagsmile.com",
"payout_currency": "BRL",
"source_currency": "BRL"
}
Sorted parameter before hash:
account_digit=4&account_number=1234567&account_type=CHECKING&additional_remark=1234567_test&amount=10.00&bankcode=001&branch=0001&custom_code=1234567&document_id=50284414727&document_type=CPF&fee=merchant&name=Test User Name¬ify_url=https://www.pagsmile.com&payout_currency=BRL&source_currency=BRL
Concatenate sorted_params with app_key (exmaple app key ABCDE) :
account_digit=4&account_number=1234567&account_type=CHECKING&additional_remark=1234567_test&amount=10.00&bankcode=001&branch=0001&custom_code=1234567&document_id=50284414727&document_type=CPF&fee=merchant&name=Test User Name¬ify_url=https://www.pagsmile.com&payout_currency=BRL&source_currency=BRLABCDE
sha256 hash
b15f900705867ecc3f66088054c14a80f9f12b1fb31c82320c4cbfe181876abb