Server-Side Payment Verification
Before you deliver that product or service, make sure the payment actually happened — no trust falls here. This guide walks you through verifying a SkyPay transaction securely from your backend.
When to Verify
Always verify payments after redirect and before fulfillment. Just because someone saw a "success" screen doesn’t mean the money's landed.
Environment URLs
| Environment | Base API URL | Note |
|---|---|---|
| Live | https://api.skypay.dev | Note: This uses api. |
API Request Details
| Element | Value / Description |
|---|---|
| Method | GET |
| Endpoint | /api/v1/checkout/payments-verify/{code} |
| Base URL | Depends on environment (Live or UAT) |
| Path Param | code — The unique order/payment ID used in the checkout |
| Header | Key: YOUR_API_KEY |
Replace {code} with your order's unique identifier.
Axios Example
axios.get('https://api.skypay.dev/api/v1/checkout/payments-verify/ORDER123', {
headers: {
Key: 'YOUR_API_KEY'
}
})
.then(res => {
if (res.data?.data?.status === 'complete') {
// Fulfill the order
} else {
// Handle failed or pending payment
}
})
.catch(err => {
// Handle request failure
})Detailed Response Format
The verification endpoint returns a comprehensive PaymentResource object. Here’s exactly what you get:
| Field | Type | Description |
|---|---|---|
id | uuid | Unique SkyPay transaction ID |
code | string | Your unique order identifier |
status | string | Current status (e.g., complete, pending) |
amount | float | Base amount in NPR |
mode | string | Integration mode (API, Manual, Assisted) |
provider_name | string | Payment provider used (e.g., eSewa, Khalti) |
merchant_amount | float | Final net amount received by merchant |
payment_data | object | Raw data returned from the payment provider (eSewa, Khalti, etc.) |
created_at | timestamp | When the session was initialized |
Provider Specific Data (payment_data)
The payment_data object contains the raw response from the payment provider. This is useful if you need provider-specific transaction IDs or audit logs.
```json [eSewa]
{
"status": "COMPLETE",
"total_amount": "1000.0",
"transaction_uuid": "SKY-PQ-123",
"transaction_code": "000X123",
"product_code": "EPAYTEST"
}
```
<!-- slide -->
```json [Khalti]
{
"pidx": "HT69Z7Y8...",
"status": "Completed",
"amount": 100000,
"transaction_id": "KHL-TXN-456",
"total_amount": 100000,
"fee": 0
}
```
<!-- slide -->
```json [Moru]
{
"mpi": "MORU-123",
"moru_txn_identifier": "MTI-789",
"state": "Completed",
"amount": "1000.00",
"completed": true
}
```Sample Full Response
{
"status": true,
"message": "Existing payment found",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"code": "ORDER123",
"status": "complete",
"amount": 1000.0,
"gross_amount": 1000.0,
"merchant_amount": 973.7,
"provider_name": "Khalti",
"provider_code": "khalti",
"mode": "API",
"payment_data": {
"pidx": "HT69Z7Y8...",
"status": "Completed",
"transaction_id": "KHL-TXN-456"
},
"created_at": "2024-03-20T10:00:00Z",
"expires_at": "2024-03-20T10:15:00Z"
}
} Check if status is "complete". That means money has been received.Other Status Values
| Status | Meaning |
|---|---|
complete | Payment successful. Proceed to fulfill. |
waiting | Manual payment marked as paid. Awaiting merchant verification. |
pending | Payment session is active but user hasn't completed it. |
cancelled | User cancelled or let the session time out. |
failed | Provider validation failed. |
invalid | Technical error or mismatch in transaction data. |
Pro Tips
- Always verify from the backend — never rely solely on frontend redirects.
- Base64
datafromsuccess_urlis not enough — use this endpoint to confirm. - Handle errors gracefully and log everything for support/debugging.
Ready to Test?
Sign up 👉 web.skypay.dev to simulate and verify payments.
SkyPay — Because verifying payments is cooler than getting scammed