Api References
Refund Order
Processes a refund for an existing order.
Endpoint
POST https://merchant.dv.vai247.pro/api/v1/payment-gateway/order/refund
Required Headers
| Header | Type | Required | Description |
|---|---|---|---|
X-Api-Key | string | Yes | Your API key |
X-Timestamp | string | Yes | Unix timestamp in seconds |
X-Signature | string | Yes | HMAC-SHA256 signature (see below) |
X-Idempotent-Key | string | Yes | Unique key to prevent duplicate refunds (UUID recommended) |
Important:
- The
X-Signatureheader requires HMAC-SHA256 signature generation using your API secret - The
X-Idempotent-Keyheader is required to prevent accidental duplicate refunds - Use a unique identifier (UUID) for each refund operation
Generating the Signature
The X-Signature header must contain an HMAC-SHA256 signature of your request:
Formula:
message = rawPayload + timestamp
signature = HMAC-SHA256(message, api_secret)
Where:
rawPayload= JSON request body as a string (e.g.,{"orderId":1234567890,"refundAmount":5.25})timestamp= Unix timestamp in seconds (same value asX-Timestampheader)api_secret= Your API secret from DVPay mobile app
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
orderId | number | Yes | Order identifier to refund |
refundAmount | number | Yes | Refund amount (must be ≤ original amount) |
Code Examples
package main
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
"time"
"github.com/google/uuid"
)
type RefundRequest struct {
OrderID int64 `json:"orderId"`
RefundAmount float64 `json:"refundAmount"`
}
type RefundResponse struct {
AccountName string `json:"accountName"`
AccountNumber string `json:"accountNumber"`
Amount float64 `json:"amount"`
Currency string `json:"currency"`
OrderID int64 `json:"orderId"`
Remark string `json:"remark"`
TransactionDate string `json:"transactionDate"`
TransactionID int64 `json:"transactionId"`
}
func generateSignature(secret, timestamp, rawPayload string) string {
// Create message: rawPayload + timestamp
message := rawPayload + timestamp
// Create HMAC with SHA256
h := hmac.New(sha256.New, []byte(secret))
h.Write([]byte(message))
// Return hex digest
return hex.EncodeToString(h.Sum(nil))
}
func refundOrder(orderID int64, amount float64, apiKey, apiSecret string) (*RefundResponse, error) {
url := "https://merchant.dv.vai247.pro/api/v1/payment-gateway/order/refund"
payload := RefundRequest{
OrderID: orderID,
RefundAmount: amount,
}
jsonData, err := json.Marshal(payload)
if err != nil {
return nil, err
}
rawPayload := string(jsonData)
// Generate timestamp
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
// Generate signature
signature := generateSignature(apiSecret, timestamp, rawPayload)
// Generate idempotent key
idempotentKey := uuid.New().String()
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
return nil, err
}
// Add authentication headers
req.Header.Set("X-Api-Key", apiKey)
req.Header.Set("X-Timestamp", timestamp)
req.Header.Set("X-Signature", signature)
req.Header.Set("X-Idempotent-Key", idempotentKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var result RefundResponse
if err := json.Unmarshal(body, &result); err != nil {
return nil, err
}
return &result, nil
}
func main() {
refund, err := refundOrder(1234567890, 5.25, "your-api-key", "your-api-secret")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Transaction ID: %d\n", refund.TransactionID)
fmt.Printf("Order ID: %d\n", refund.OrderID)
fmt.Printf("Amount: %.2f %s\n", refund.Amount, refund.Currency)
}
const axios = require('axios');
const crypto = require('crypto');
const { v4: uuidv4 } = require('uuid');
function generateSignature(secret, timestamp, rawPayload) {
// Create HMAC with SHA256
const hmac = crypto.createHmac('sha256', secret);
// Create message: rawPayload + timestamp
const message = rawPayload + timestamp.toString();
// Update HMAC with message and get hex digest
hmac.update(message);
return hmac.digest('hex');
}
async function refundOrder(orderId, amount, apiKey, apiSecret) {
const url = 'https://merchant.dv.vai247.pro/api/v1/payment-gateway/order/refund';
// Create payload
const payload = {
orderId: orderId,
refundAmount: amount
};
const rawPayload = JSON.stringify(payload);
// Generate timestamp
const timestamp = Math.floor(Date.now() / 1000);
// Generate signature
const signature = generateSignature(apiSecret, timestamp, rawPayload);
// Generate idempotent key
const idempotentKey = uuidv4();
// Make request
const headers = {
'X-Api-Key': apiKey,
'X-Timestamp': timestamp.toString(),
'X-Signature': signature,
'X-Idempotent-Key': idempotentKey,
'Content-Type': 'application/json'
};
try {
const response = await axios.post(url, payload, { headers });
return response.data;
} catch (error) {
console.error('Error processing refund:', error.response?.data || error.message);
throw error;
}
}
// Usage
(async () => {
try {
const refund = await refundOrder(1234567890, 5.25, 'your-api-key', 'your-api-secret');
console.log('Transaction ID:', refund.data.transactionId);
console.log('Order ID:', refund.data.orderId);
console.log('Amount:', `${refund.data.amount} ${refund.data.currency}`);
} catch (error) {
console.error('Failed to process refund');
}
})();
Response
{
"statusCode": 200,
"message": "Success",
"data": {
"accountName": "John Doe",
"accountNumber": "123456789",
"amount": 5.25,
"currency": "USD",
"orderId": 1234567890,
"remark": "",
"transactionDate": "2026-03-02T10:35:00Z",
"transactionId": 9876543210
},
"traceId": "trace_abc123"
}
Notes
- Signature Required: All refund requests must include a valid
X-Signatureheader generated using HMAC-SHA256 - Idempotency: Each refund request requires a unique
X-Idempotent-Keyheader. If you retry a request with the same key, the API will return the original response without processing a duplicate refund - Refund amount cannot exceed the original order amount
- Partial refunds are supported
- Refunds may take 3-5 business days to process
X-App-Id header has been removed. Use signature-based authentication with X-Signature header instead. See v1.4.0 Release Notes for migration guide.