Getting Started
Wallet-Pay Quick Start
Integration Sequence Diagram
Take an e-commerce application as an example:

Dashboard Operation Instructions
Dashboard
is the management backend for Wallet-Pay
, providing functions such as creating applications, configuring applications, and managing orders.
You can consult our customer service for the access address of the Dashboard
.
Technical Support TG: @Openweb3WalletPay
Dashboard
entry link:
Telegram: https://tg-socialwallet.wallet-pay.openweb3.io
Dejoy: https://dejoy-socialwallet.wallet-pay.openweb3.io
Register Account
You can register with an email or log in with Google, and follow the instructions to complete the 2FA
registration and binding.
Create Team
After registering an account, you will be redirected to the team list page by default.
If you don't have a team, you can contact Technical Support
to apply to join an existing team or create a new one.
By clicking the Create team
button, you can follow the instructions to create a new team.

After submitting the team information, you need to contact Technical Support
for approval.

After approval, or after being invited to a team, you can manage applications and view information such as accounts, orders, and refunds in the Dashboard
.

Create Application
After logging into the Dashboard
and entering a team, you can create a new application by clicking Apps
-> New App
.

Configure Application
Register API Key
API Key
If you need to use the SDK to make OpenApi
interface calls, including creating orders, querying order status, etc., you need to register an API Key
in the Dashboard
first.
The ED25519
algorithm APIKEY
is used here. You can refer to the following method to generate the key pair.
# Generate a private key and save it to the `private.key.pem` file
openssl genpkey -algorithm ed25519 -out private_key.pem
# Extract the public key from the private key and save it to the `public.key.pem` file
openssl pkey -in private_key.pem -pubout -out public_key.pem
# Export the private key in hexadecimal format
openssl pkey -in private_key.pem -text | \
grep 'priv:' -A 3 | tail -n +2 | tr -d ':\n '
# Export the public key in hexadecimal format
openssl pkey -pubin -in public_key.pem -text | \
grep 'pub:' -A 3 | tail -n +2 | tr -d ':\n '
After the key pair is generated, register the public key to the application through Apps
-> App Settings
-> Register API Key
.
The private key needs to be kept properly by yourself and will be used when using the SDK.

Configure Webhook
Webhook
If you need to use Webhook
for order status callback notifications, you need to configure Webhook
in the Dashboard
first.
Add a webhook endpoint
in Apps
-> App Settings
-> Add Webhook
.
The detailed description of Notification Events
can be found at Webhook Events.

SDK Integration
You can interact with the Wallet-Pay
service through the SDK
, which provides support for multiple languages, including Golang
, NodeJS
, and Java
.
For the interfaces and their parameter descriptions involved in the SDK, please refer to the OpenAPI
documentation WALLETPAY OPENAPI DOCUMENTATION .
Install SDK Dependencies
Golang
Add the following dependency to your go.mod
file:
require github.com/openweb3-io/wallet-pay-openapi/go latest
Then run the go mod tidy
command to download the dependencies.
NodeJS
Use the following command to install the SDK:
pnpm i @openweb3-io/wallet-pay
# or
yarn add @openweb3-io/wallet-pay
# or
npm i @openweb3-io/wallet-pay
Java
If you are using maven
for project management, you can add the following dependency to your pom.xml
file:
<dependency>
<groupId>io.openweb3</groupId>
<artifactId>walletpay</artifactId>
<version>0.2.13</version>
</dependency>
If you are using gradle
for project management, you can add the following dependency to your build.gradle
file:
implementation 'io.openweb3:walletpay:0.2.13'
Initialize SDK
SDK initialization involves two parameters, ApiKey
and Secret
, which correspond to the public and private keys generated in the Register API Key step. ApiKey
is the public key, and Secret
is the private key.
Golang
import (
"log"
walletpay "github.com/openweb3-io/wallet-pay-openapi/go"
)
const (
ApiKey = "YOUR_API_KEY"
Secret = "YOUR_SECRET"
)
func main() {
// Initialize ApiClient
client := walletpay.New(&walletpay.ApiClientOptions{
ApiKey: ApiKey,
Secret: Secret,
})
}
NodeJS
import { ApiClient } from "@openweb3-io/wallet-pay";
const ApiKey = "YOUR_API_KEY";
const Secret = "YOUR_SECRET";
const client = new ApiClient(ApiKey, Secret, {});
Java
import io.openweb3.walletpay.ApiClient;
import io.openweb3.walletpay.ApiClientOptions;
public class WalletPayExample {
public static void main(String[] args) {
String apiKey = "YOUR_API_KEY";
String secret = "YOUR_SECRET";
ApiClient apiClient = new ApiClient(
new ApiClientOptions()
.apiKey(apiKey)
.privateKey(secret)
);
}
}
PHP
WalletPay
does not currently support an SDK
for the PHP
language.
The interface signature algorithm can refer to the description in Authentication.
Sample code is as follows:
<?php
// The sodium extension is required (PHP >= 7.2.0)
if (!extension_loaded('sodium')) {
die("Sodium extension required");
}
$body = 'post body data';
$uri = 'request uri';
$timestamp = 'current timestamp';
$content = $body . $uri . $timestamp;
// SHA-256 hash calculation
$hash = hash('sha256', $content, true);
// Decode API secret
$apiSecret = hex2bin('YOUR_API_SECRET');
// Generate key pair from seed
$keyPair = sodium_crypto_sign_seed_keypair($apiSecret);
$secretKey = sodium_crypto_sign_secretkey($keyPair);
// Ed25519 signature
$signature = sodium_crypto_sign_detached($hash, $secretKey);
echo "Signature: " . bin2hex($signature) . PHP_EOL;
Create Order
Golang
import (
"context"
"encoding/json"
"fmt"
"log"
walletpay "github.com/openweb3-io/wallet-pay-openapi/go"
)
const (
ApiKey = "YOUR_API_KEY"
Secret = "YOUR_SECRET"
)
func create() {
// Initialize ApiClient
client := walletpay.New(&walletpay.ApiClientOptions{
Debug: true,
ApiKey: ApiKey,
Secret: Secret,
})
currencyCode := "USDT"
amount := int32(1)
currency, err := client.Currencies.FindByCode(context.Background(), currencyCode)
if err != nil {
log.Fatal(err)
}
order, err := client.Orders.Create(context.Background(), &walletpay.CreateOrderRequest{
Currency: currencyCode,
Amount: fmt.Sprintf("%d", amount*currency.Decimals), // 1 USDT
Expiration: walletpay.PtrInt32(10),
Creator: walletpay.PtrString("creator_user_id"),
})
if err != nil {
log.Fatal(err)
}
buf, _ := json.MarshalIndent(order, "", " ")
log.Printf(string(buf))
}
NodeJS
import { ApiClient } from "@openweb3-io/wallet-pay";
const ApiKey = "YOUR_API_KEY";
const Secret = "YOUR_SECRET";
const client = new ApiClient(ApiKey, Secret, {});
const USDT = "USDT";
const AMOUNT = 1;
const { decimals } = await client.currencies.findByCode(USDT);
const order = await client.orders.create({
currency: USDT,
amount: (AMOUNT * (10 ** decimals)).toString(),
creator: "creator_user_id",
});
console.log(order);
Java
import io.openweb3.walletpay.*;
import io.openweb3.walletpay.models.*;
import java.math.BigInteger;
public class WalletPayExample {
public static void main(String[] args) {
String apiKey = "YOUR_API_KEY";
String secret = "YOUR_SECRET";
ApiClient apiClient = new ApiClient(
new ApiClientOptions()
.apiKey(apiKey)
.privateKey(secret)
);
String currencyCode = "USDT";
String amount = "1"; // readable amount
// get currency info
final Currency currency = apiClient.currencies().findByCode(currencyCode);
System.out.println("currency: " + currency);
// create order
BigInteger amountInBaseUnit = new BigInteger(amount).multiply(BigInteger.TEN.pow(currency.getDecimals()));
CreateOrderRequest orderIn = new CreateOrderRequest()
.amount(amountInBaseUnit.toString())
.currency(currencyCode)
.creator("creator_user_id");
final Order orderInfo = apiClient.orders().create(orderIn);
System.out.println("orderInfo: " + orderInfo);
// list orders
final PageOrder orders = apiClient.orders().list(
new OrderListOptions().currency("CoinBeta").size(20)
);
System.out.println("orderInfos: " + orders);
}
}
Pay Order
Paying for an order requires launching the wallet for payment. The general process is as follows:
- The application frontend sends a request to the application backend to create an order.
- The application backend creates an order through the SDK and returns the order information to the frontend.
- After the application frontend receives the order information, it launches the wallet for payment through a specific URL.
- After the wallet receives the payment request, it will jump to the payment interface according to the order information and wait for the user to confirm the payment.
- After the payment is completed, the wallet will call back the
webhook
interface of the application backend. After the application backend receives the callback, it will perform subsequent processing according to the order status.
The frontend URL for launching the wallet application is as follows:
# .env environment configuration
# telegram mini app
TELEGRAM_MANIAPP_DOMAIN=https://t.me/socialwalletbot/SocialWallet
# openweb3 mini app
OPENWEB3_MINIAPP_DOMAIN=https://t.me/wallet_bot/wallet
On the frontend, by using the host above and appending parameters, you can launch the wallet for payment.
Taking the Telegram
mini app as an example:
// example.tsx
const link = `${process.env.TELEGRAM_MANIAPP_DOMAIN}?startapp=Pay_${order_id}`;
window.open(link);
Refund Order
Golang
import (
"context"
"encoding/json"
"log"
"fmt"
walletpay "github.com/openweb3-io/wallet-pay-openapi/go"
)
const (
ApiKey = "YOUR_API_KEY"
Secret = "YOUR_SECRET"
)
func createRefund() {
// Initialize ApiClient
client := walletpay.New(&walletpay.ApiClientOptions{
Debug: true,
ApiKey: ApiKey,
Secret: Secret,
})
currencyCode := "USDT"
amount := int32(1)
currency, err := client.Currencies.FindByCode(context.Background(), currencyCode)
if err != nil {
log.Fatal(err)
}
refund, err := client.Refunds.Create(context.Background(), &walletpay.CreateRefundRequest{
OrderId: "order_123",
Amount: fmt.Sprintf("%d", amount*currency.Decimals), // 1 USDT
Note: walletpay.PtrString("test"),
})
if err != nil {
log.Fatal(err)
}
buf, _ := json.MarshalIndent(refund, "", " ")
log.Printf(string(buf))
}
NodeJS
import { ApiClient } from "@openweb3-io/wallet-pay";
const ApiKey = "YOUR_API_KEY";
const Secret = "YOUR_SECRET";
const client = new ApiClient(ApiKey, Secret, {});
const USDT = "USDT";
const AMOUNT = 1;
const { decimals } = await client.currencies.findByCode(USDT);
const refund = await client.refunds.create({
"orderId": "1234567890",
"amount": (AMOUNT * (10 ** decimals)).toString(),
"note": "test refund",
});
console.log(refund);
Java
import io.openweb3.walletpay.*;
import io.openweb3.walletpay.models.*;
import java.math.BigInteger;
public class WalletPayExample {
public static void main(String[] args) {
String apiKey = "YOUR_API_KEY";
String secret = "YOUR_SECRET";
ApiClient apiClient = new ApiClient(
new ApiClientOptions()
.apiKey(apiKey)
.privateKey(secret)
);
String currencyCode = "USDT";
String amount = "1"; // readable amount
// get currency info
final Currency currency = apiClient.currencies().findByCode(currencyCode);
System.out.println("currency: " + currency);
BigInteger amountInBaseUnit = new BigInteger(amount).multiply(BigInteger.TEN.pow(currency.getDecimals()));
CreateRefundRequest refundIn = new CreateRefundRequest().
orderId("order_id").
amount(amountInBaseUnit.toString());
Refund refundInfo = apiClient.refunds().create(refundIn);
System.out.println("refundInfo: " + refundInfo);
}
}
Callback Handling
Callback handling mainly consists of 3 parts:
- Verify signature
- Event deduplication
- Process event
For a detailed description of callbacks, please refer to walletpay-introduction-to-webhooks.
The PublicKey
required for Webhook callback verification can be found in the Dashboard
under settings -> developer
.
Sample code for webhook signature verification is as follows:
Golang
import (
"log"
walletpay "github.com/openweb3-io/wallet-pay-openapi/go"
)
const (
publicKey = "YOUR_PUBLIC_KEY"
)
func webhook() {
client, err := walletpay.NewWebhookClient(publicKey)
if err != nil {
log.Fatal(err)
}
payload := []byte("content from webhook request body")
signature := "content from webhook request header: X-Signature"
// Verify signature
err = client.Verify(payload, signature)
if err != nil {
log.Fatal("signature verify failed")
}
// TODO Signature verification successful, process related business
}
NodeJS
import { WebhookClient } from "@openweb3-io/wallet-pay";
const PUBLICKEY = `-----BEGIN RSA PUBLIC KEY-----
YOUR KEY CONTENT
-----END RSA PUBLIC KEY-----`;
// Request headers with X-Signature and Payload, Verify the signature method
const payload = 'content from webhook request body';
const signature = 'content from webhook request header: X-Signature'
const webhookClient = new WebhookClient(PUBLICKEY);
const result = webhookClient.verify(payload, signature);
if (result) {
// TODO Signature verification successful, process related business
} else {
// Signature verification failed, callback is not credible, please ignore
}
Java
import io.openweb3.walletpay.*;
public class WalletPayExample {
public static void main(String[] args) {
String publicKey = "YOUR_PUBLIC_KEY";
String payload = "content from webhook request body";
String signature = "content from webhook request header: X-Signature";
// verify the webhook payload
WebhookClient webhookClient = new WebhookClient(publicKey);
boolean ok = webhookClient.verify(payload, signature);
System.out.println("verify " + (ok? "success" : "fail"));
if (ok) {
// TODO process the webhook event
} else {
// TODO handle the verification failure
}
}
}
PHP
function verify($data, $publicKey, $signature) {
// PEM decode (PHP will automatically handle PEM format)
$pubKey = openssl_pkey_get_public($publicKey);
if ($pubKey === false) {
throw new Exception("Public key error: " . openssl_error_string());
}
// Base64 decode the signature
$signBytes = base64_decode($signature, true);
if ($signBytes === false) {
error_log("Signature contains invalid characters: $signature");
throw new Exception("Invalid base64 signature");
}
// SHA256 hash calculation
$hashed = hash('sha256', $data, true);
// Verify signature
$result = openssl_verify(
$hashed, // Use the hashed data for verification
$signBytes,
$pubKey,
OPENSSL_ALGO_SHA256
);
// Free key resource
openssl_free_key($pubKey);
// Handle verification result
if ($result === 1) {
return null; // Verification successful
} elseif ($result === 0) {
return new Exception("Invalid signature");
} else {
throw new Exception("Verification error: " . openssl_error_string());
}
}
// Test execution code
try {
$data = "content from webhook request body";
$publicKey = "your public key from wallet-pay dashboard";
$signature = "content from webhook request header: X-Signature";
$result = verify($data, $publicKey, trim($signature));
if ($result === null) {
echo "verify success\n";
} else {
echo "verify failed: " . $result->getMessage() . "\n";
}
} catch (Exception $e) {
echo "exception: " . $e->getMessage() . "\n";
}
Updated 9 days ago