Skip to content

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}");
        }
    } 
}