Appearance
SDK
Java SDK
SDK 下载
使用指南
shell
# manual installation
mvn install:install-file -Dfile=pay-sdk-1.0.0-SNAPSHOT.jar -DgroupId=com.examplepay -DartifactId=pay-sdk -Dversion=1.0.0-SNAPSHOT -Dpackaging=jar -DpomFile=pom.xml
在项目中使用
xml
<dependency>
<groupId>com.examplepay</groupId>
<artifactId>pay-sdk</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
示例
WARNING
- 示例仅作参考,请根据实际情况替换相关参数值
- 验证签名前,强烈建议阅读 验证签名指南
java
package com.examplepay.sdk.authorization.example;
import com.examplepay.sdk.authorization.AuthorizationUtil;
public class SignExample {
public static void main(String[] args) {
String signMethod = "V2_SHA256";
String appId = "483f6c9c743b4a9bbd34bee0c9c81eb7";
String appSecret = "19200e1478524aceb629acbc570d15d3";
String url = "https://{{gateway_domain}}/pg/v2/payment/create";
String requestData = "{\"merchantTradeNo\":\"MTU-116717\",\"amount\":\"1.00\",\"currency\":\"INR\",\"description\":\"payment test\",\"payer\":{\"userId\":\"11\",\"name\":\"testName\",\"email\":\"[email protected]\",\"phone\":\"00000000\"},\"payMethod\":{\"type\":\"UPI\"},\"tradeEnv\":{\"ip\":\"127.0.0.1\",\"deviceId\":\"02efc74d-3988-4f0d-8cc8-0cb78bded719\"},\"merchantAttach\":\"merchant attach\",\"notifyUrl\":\"https://example.com/notifyurl\",\"returnUrl\":\"https://example.com/returnurl\"}";
String authorization = AuthorizationUtil.createAuthorization(signMethod, appId, appSecret, "POST", url, requestData);
System.out.println(authorization);
}
}
Node.js SDK
SDK 下载
示例
WARNING
- 示例仅作参考,请根据实际情况替换相关参数值
- 验证签名前,强烈建议阅读 验证签名指南
js
import fetch from 'node-fetch';
import SignUtil from '../src/signUtil.js';
const signUtil = new SignUtil();
const signMethod = 'V2_SHA256';
const appId = '483f6c9c743b4a9bbd34bee0c9c81eb7';
const appSecret = '19200e1478524aceb629acbc570d15d3';
const timestamp = new Date().getTime();
const nonce = signUtil.createHex(32);
const url = 'https://{{gateway_domain}}/pg/v2/payment/create';
const requestData = {
"merchantTradeNo": "MTU-11677",
"amount": "1.00",
"currency": "INR",
"description": "payment test",
"payer": {
"userId": "test_id",
"name": "testName",
"email": "[email protected]",
"phone": "00000000"
},
"payMethod": {
"type": "UPI"
},
"tradeEnv": {
"ip": "127.0.0.1",
"deviceId": "02efc74d-3988-4f0d-8cc8-0cb78bded719"
},
"merchantAttach": "merchant attach",
"notifyUrl": "https://example.com/notifyurl",
"returnUrl": "https://example.com/returnurl"
};
// 计算签名
const sign = signUtil.signRequest(signMethod, appId, appSecret, "POST", url, requestData, timestamp, nonce);
// 生成请求头
const headers = {
'Content-Type': 'application/json',
'Authorization': `${signMethod} appId=${appId},sign=${sign},timestamp=${timestamp},nonce=${nonce}`
};
// 使用 fetch 发送请求
fetch(url, {
method: 'POST',
headers: headers,
body: requestData
})
.then(res => {
console.log(`statusCode: ${res.status}`);
return res.text().then(responseData => {
const responseHeader = res.headers.get('authorization');
console.log(responseHeader);
console.log(responseData);
// check response sign
const signInfo = signUtil.parseAuthorizationHeader(responseHeader);
const resign = signUtil.signRequest(signInfo.method, appId, appSecret, "POST", url, responseData, signInfo.timestamp, signInfo.nonce);
console.log(appId, "\t", signInfo.appId);
console.log(resign, "\t", signInfo.sign);
});
})
.catch(error => {
console.error(error);
});
PHP SDK
SDK 下载
示例
WARNING
- 示例仅作参考,请根据实际情况替换相关参数值
- 验证签名前,强烈建议阅读 验证签名指南
php
<?php
use Com\ExamplePay\Sdk\SignUtil;
require_once "../src/SignUtil.php";
$signUtil = new SignUtil();
$signMethod = 'V2_SHA256';
$appId = '483f6c9c743b4a9bbd34bee0c9c81eb7';
$appSecret = '19200e1478524aceb629acbc570d15d3';
$timestamp = time() * 1000; // in milliseconds
// generate random nonce
$nonce = bin2hex(random_bytes(16));
$url = 'https://{{gateway_domain}}/pg/v2/payment/create';
$requestData = '{
"merchantTradeNo": "MTU-11677",
"amount": "1.00",
"currency": "INR",
"description": "payment test",
"payer": {
"userId": "test_id",
"name": "testName",
"email": "[email protected]",
"phone": "00000000"
},
"payMethod": {
"type": "UPI"
},
"tradeEnv": {
"ip": "127.0.0.1",
"deviceId": "02efc74d-3988-4f0d-8cc8-0cb78bded719"
},
"merchantAttach": "merchant attach",
"notifyUrl": "https://example.com/notifyurl",
"returnUrl": "https://example.com/returnurl"
}';
// Calculate signature
$sign = $signUtil->signRequest($signMethod, $appId, $appSecret, "POST", $url, $requestData, $timestamp, $nonce);
// Generate request header
$header = [
'key' => 'Authorization',
'value' => $signMethod . ' appId=' . $appId . ',sign=' . $sign . ',timestamp=' . $timestamp . ',nonce=' . $nonce
];
print_r($header);
$options = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\n" .
"Authorization: " . $header['value'] . "\r\n",
'content' => $requestData
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
if ($response === false) {
// Handle error
echo "Error: Unable to fetch response.";
} else {
// Handle response
$responseHeaders = $http_response_header;
$responseData = $response;
// Check response sign
$responseHeader = "";
foreach ($responseHeaders as $header) {
if (strpos($header, 'Authorization:') === 0) {
$responseHeader = $header;
break;
}
}
$responseHeader = str_replace('Authorization: ', '', $responseHeader);
$signInfo = $signUtil->parseAuthorizationHeader($responseHeader);
$resign = $signUtil->signRequest($signInfo['method'], $appId, $appSecret, "POST", $url, $responseData, $signInfo['timestamp'], $signInfo['nonce']);
assert($appId == $signInfo['appId'], "response appId should be equal request appId.");
assert($resign == $signInfo['sign'], "resign should be equals response sign");
}
获取 HTTP Body
php
// Webhook 场景
$rawBody = $request->getContent();
Go SDK
SDK 下载
示例
WARNING
- 示例仅作参考,请根据实际情况替换相关参数值
- 验证签名前,强烈建议阅读 验证签名指南
go
package main
import (
"bytes"
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"net/http"
"strconv"
"strings"
"time"
"pay-go-sdk/signutil"
)
func main() {
signMethod := "V2_SHA256"
appId := "483f6c9c743b4a9bbd34bee0c9c81eb7"
appSecret := "19200e1478524aceb629acbc570d15d3"
timestamp := strconv.FormatInt(time.Now().UnixNano()/int64(1e6), 10)
nonce := generateNonce(16)
// 替换为实际的网关域名
url := "https://gateway.examplepay.com/pg/v2/payment/create"
requestData := `{
"merchantTradeNo": "MTU-11677",
"amount": "1.00",
"currency": "INR",
"description": "payment test",
"payer": {
"userId": "test_id",
"name": "testName",
"email": "[email protected]",
"phone": "00000000"
},
"payMethod": {
"type": "UPI"
},
"tradeEnv": {
"ip": "127.0.0.1",
"deviceId": "02efc74d-3988-4f0d-8cc8-0cb78bded719"
},
"merchantAttach": "merchant attach",
"notifyUrl": "https://example.com/notifyurl",
"returnUrl": "https://example.com/returnurl"
}`
sign, err := signutil.SignRequest(signMethod, appId, appSecret, "POST", url, requestData, timestamp, nonce)
if err != nil {
fmt.Println("Error signing request:", err)
return
}
authHeader := fmt.Sprintf("%s appId=%s,sign=%s,timestamp=%s,nonce=%s", signMethod, appId, sign, timestamp, nonce)
fmt.Println("authHeader:", authHeader)
req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(requestData)))
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", authHeader)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error sending request:", err)
return
}
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
}
}(resp.Body)
responseBody, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response:", err)
return
}
fmt.Println("Response Status:", resp.Status)
fmt.Println("Response Body:", string(responseBody))
responseAuthHeader := getAuthorizationHeader(resp.Header)
if responseAuthHeader == "" {
fmt.Println("No Authorization header found in response.")
return
}
signInfo, err := signutil.ParseAuthorizationHeader(responseAuthHeader)
if err != nil {
fmt.Println("Error parsing Authorization header:", err)
return
}
resign, err := signutil.SignRequest(signInfo["method"].(string), appId, appSecret, "POST", url, string(responseBody), signInfo["timestamp"].(string), signInfo["nonce"].(string))
if err != nil {
fmt.Println("Error resigning response:", err)
return
}
if appId != signInfo["appId"].(string) {
fmt.Println("Error: response appId does not match request appId.")
} else if resign != signInfo["sign"].(string) {
fmt.Println("Error: resign does not match response sign.")
} else {
fmt.Println("Signature validation passed.")
}
}
func generateNonce(length int) string {
b := make([]byte, length)
_, err := rand.Read(b)
if err != nil {
fmt.Println("Error generating nonce:", err)
return ""
}
return hex.EncodeToString(b)
}
func getAuthorizationHeader(headers http.Header) string {
for k, v := range headers {
if strings.ToLower(k) == "authorization" {
return strings.Join(v, "")
}
}
return ""
}
C# SDK
SDK 下载
示例
WARNING
- 示例仅作参考,请根据实际情况替换相关参数值
- 验证签名前,强烈建议阅读 验证签名指南
csharp
using System.Text;
namespace Com.ExamplePay.Sdk.Examples;
public static class SignRequestExample
{
public static void Main()
{
SignRequest().Wait();
}
public static async Task SignRequest()
{
try
{
const string signMethod = "V2_SHA256";
const string appId = "483f6c9c743b4a9bbd34bee0c9c81eb7";
const string appSecret = "19200e1478524aceb629acbc570d15d3";
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
var nonce = SignUtil.CreateHex(32);
// Replace request domain with gateway domain
var url = "https://gateway.examplepay.com/pg/v2/payment/create";
var requestData = """
{
"merchantTradeNo": "MTU-11677",
"amount": "1.00",
"currency": "INR",
"description": "payment test",
"payer": {
"userId": "test_id",
"name": "testName",
"email": "[email protected]",
"phone": "00000000"
},
"payMethod": {
"type": "UPI"
},
"tradeEnv": {
"ip": "127.0.0.1",
"deviceId": "02efc74d-3988-4f0d-8cc8-0cb78bded719"
},
"merchantAttach": "merchant attach",
"notifyUrl": "https://example.com/notifyurl",
"returnUrl": "https://example.com/returnurl"
}
""";
//Console.WriteLine(requestData);
// Calculate signature
var sign = SignUtil.SignRequest(signMethod, appId, appSecret, "POST", url, requestData, timestamp,
nonce);
// Generate request header
var authorizationHeader = $"{signMethod} appId={appId},sign={sign},timestamp={timestamp},nonce={nonce}";
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new StringContent(requestData, Encoding.UTF8, "application/json")
};
request.Headers.Add("Authorization", authorizationHeader);
var response = await client.SendAsync(request);
var responseData = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
Console.WriteLine("Error: Unable to fetch response.");
return;
}
// Handle response
if (response.Headers.Contains("Authorization"))
{
var responseHeader = response.Headers.GetValues("Authorization").FirstOrDefault();
if (responseHeader != null)
{
// Check response sign
var signInfo = SignUtil.ParseAuthorizationHeader(responseHeader);
var resign = SignUtil.SignRequest(signInfo.Method, appId, appSecret, "POST", url, responseData,
signInfo.Timestamp, signInfo.Nonce);
if (appId != signInfo.AppId)
{
throw new Exception("Response appId should be equal to request appId.");
}
if (resign != signInfo.Sign)
{
throw new Exception("Resign should be equal to response sign.");
}
Console.WriteLine("Response signature is valid.");
Console.WriteLine($"{resign}\t{signInfo.Sign}");
}
}
}
catch (Exception ex)
{
// If any assertion fails
Console.WriteLine($"Sign Request failed: {ex.Message}");
}
}
}