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

HeaderTypeRequiredDescription
X-Api-KeystringYesYour API key
X-TimestampstringYesUnix timestamp in seconds
X-SignaturestringYesHMAC-SHA256 signature (see below)
X-Idempotent-KeystringYesUnique key to prevent duplicate refunds (UUID recommended)

Important:

  • The X-Signature header requires HMAC-SHA256 signature generation using your API secret
  • The X-Idempotent-Key header 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 as X-Timestamp header)
  • api_secret = Your API secret from DVPay mobile app
Getting Your API Secret: DVPay mobile app → Settings → API Configuration → Show API Secret

Request Parameters

ParameterTypeRequiredDescription
orderIdnumberYesOrder identifier to refund
refundAmountnumberYesRefund 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)
}

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-Signature header generated using HMAC-SHA256
  • Idempotency: Each refund request requires a unique X-Idempotent-Key header. 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
Migration from v1.3.0: The 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.