Refunds API
Overviewβ
The Refunds API enables you to return funds to customers for credit card charges. Issue full or partial refunds, track refund history, and handle returns seamlessly.
What are Refunds?β
Refunds are objects that represent money returned to customers:
- Full refunds - Return entire charge amount
- Partial refunds - Return portion of charge amount
- Multiple refunds - Issue several partial refunds up to original amount
- Automatic processing - Funds returned to customer's card automatically
Key Featuresβ
Flexible Refund Optionsβ
- Full or partial - Refund any amount up to original charge
- Multiple refunds - Split refund across multiple transactions
- Metadata support - Add custom data for tracking
- Instant processing - Refunds processed immediately
Easy Managementβ
- List refunds - View all refunds for a charge
- Track status - Monitor refund processing
- Search refunds - Find specific refund transactions
- Audit trail - Complete refund history
Automatic Handlingβ
- Direct to card - Funds returned to customer's original card
- No customer action - Automatic processing
- Fee handling - Transaction fees handled per policy
- Currency matching - Same currency as original charge
How Refunds Workβ
Standard Flowβ
βββββββββββ βββββββββββ βββββββββββ
β Your β β Omise β β Customerβ
β Server β β API β β Bank β
ββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ
β β β
β 1. Create refund β β
βββββββββββββββββββ>β β
β β β
β 2. Return refund β β
β<βββββββββββββββββββ€ β
β β β
β β 3. Process refund β
β βββββββββββββββββββ>β
β β β
β β 4. Funds returned β
β β<βββββββββββββββββββ€
β β β
β 5. Webhook notify β β
β<βββββββββββββββββββ€ β
β β β
Refund Timelineβ
- Immediate: Refund created in Omise system
- Processing: Sent to card network (instant)
- Customer sees: Typically 5-10 business days
- Webhook sent: When refund completes
API Endpointsβ
| Method | Endpoint | Description |
|---|---|---|
| POST | /charges/:id/refunds | Create a refund for charge |
| GET | /refunds/:id | Retrieve refund details |
| GET | /charges/:id/refunds | List all refunds for charge |
Quick Startβ
Full Refundβ
// Refund entire charge
const refund = await omise.charges.refund('chrg_test_5xuy4w91xqz7d1w9u0t');
console.log('Refund created:', refund.id);
console.log('Amount:', refund.amount);
console.log('Status:', refund.status);
Partial Refundβ
// Refund portion of charge
const refund = await omise.charges.refund('chrg_test_5xuy4w91xqz7d1w9u0t', {
amount: 50000 // Refund ΰΈΏ500 of ΰΈΏ1000 charge
});
console.log('Refunded:', refund.amount);
console.log('Original:', refund.charge.amount);
Multiple Partial Refundsβ
// Issue multiple refunds for same charge
const refund1 = await omise.charges.refund(chargeId, { amount: 30000 });
const refund2 = await omise.charges.refund(chargeId, { amount: 20000 });
// Check total refunded
const charge = await omise.charges.retrieve(chargeId);
console.log('Total refunded:', charge.refunded_amount);
console.log('Remaining:', charge.amount - charge.refunded_amount);
Common Use Casesβ
Product Returnβ
// Customer returns product
const refund = await omise.charges.refund(chargeId, {
amount: productPrice,
metadata: {
reason: 'product_return',
order_id: 'ORDER-123',
return_tracking: 'TRACK-456'
}
});
Order Cancellationβ
// Cancel order, full refund
const refund = await omise.charges.refund(chargeId, {
metadata: {
reason: 'order_cancelled',
cancelled_by: 'customer'
}
});
Partial Refund (Damaged Item)β
// Refund portion for damaged item
const refund = await omise.charges.refund(chargeId, {
amount: damageCompensation, // e.g., 30% of original
metadata: {
reason: 'partial_damage',
compensation_rate: 0.3
}
});
Refund Rulesβ
Timingβ
- Can refund: Any time after successful charge
- Cannot refund: Failed or pending charges
- Time limit: No limit (can refund years later)
Amountsβ
- Minimum: 1 unit in currency (1 satang for THB)
- Maximum: Original charge amount minus previous refunds
- Multiple: Can issue multiple partial refunds
- Total: Cannot exceed original charge amount
Eligibilityβ
- β Successful charges - Can be refunded
- β Pending charges - Cannot be refunded
- β Failed charges - Cannot be refunded
- β Partially refunded - Can refund remaining amount
Transaction Feesβ
Fee Handlingβ
- Full refund: Transaction fee may be returned (policy dependent)
- Partial refund: Fee typically not returned
- Check policy: Contact support for your account's refund fee policy
Best Practicesβ
β Do Thisβ
- Add metadata for refund reasons
- Verify charge status before refunding (must be successful)
- Check refundable amount (original - already refunded)
- Notify customer when refund is issued
- Track refund IDs in your system
- Set up webhooks for refund notifications
- Handle errors gracefully (insufficient funds, etc.)
β Don't Do Thisβ
- Don't refund pending charges (will fail)
- Don't exceed original amount (will fail)
- Don't assume instant credit (takes 5-10 days)
- Don't refund without verification (ensure legitimate)
- Don't skip reason tracking (use metadata)
Testingβ
Test Mode Refundsβ
// Test refunds work same as live
const refund = await omise.charges.refund('chrg_test_xxx', {
amount: 50000
});
// Check refund in test dashboard
console.log('Test refund:', refund.id);
Refund Failure Codesβ
When a refund fails, the failure_code attribute indicates the reason:
| Code | Message | Description |
|---|---|---|
failed_refund | "refund failed" | Refund processing error |
not_refundable | "charge cannot be refunded" | Charge status doesn't allow refund |
insufficient_refundable_amount | "amount exceeds refundable balance" | Amount greater than available |
invalid_amount | "invalid amount" | Amount is zero or negative |
refund_limit_exceeded | "refund limit exceeded" | Maximum number of refunds reached |
charge_not_found | "charge not found" | Charge ID doesn't exist |
charge_expired | "charge expired" | Cannot refund expired charge |
Refund Limitsβ
Refund Restrictions
- Time limit: Refunds must be made within 365 days of the original charge
- Partial refunds: Maximum of 15 partial refunds per charge
- Amount: Cannot exceed original charge amount minus previous refunds
Error Handlingβ
Common refund errors:
| Error Code | HTTP Status | Description | Solution |
|---|---|---|---|
not_refundable | 400 | Charge cannot be refunded | Check charge status (must be successful) |
insufficient_refundable_amount | 400 | Amount exceeds refundable balance | Check refunded_amount on charge |
invalid_amount | 400 | Amount is invalid | Verify amount > 0 and is integer |
refund_limit_exceeded | 400 | Too many partial refunds | Maximum 15 partial refunds per charge |
API Referenceβ
- Create Refund - POST /charges/:id/refunds
- Retrieve Refund - GET /refunds/:id
Related Resourcesβ
Need help? Check our Refunds Guide or contact support@omise.co