Payments and Refunds
Process payments, issue refunds, manage credit notes, and handle multi-gateway reversals
RevKeen processes payments through your connected payment gateway, handling tokenization, authorization, capture, and refunds. This guide covers the complete payment flow, refund processing, credit notes, and best practices.
Supported Payment Methods
- Credit/Debit Cards -- Visa, Mastercard, American Express, Discover, and more
- ACH Bank Transfer -- Direct bank debits for US customers (lower fees)
- Saved Cards -- Securely stored payment methods for returning customers (email verification + CVV required)
Payment Flow
RevKeen uses tokenization to ensure card data never touches your servers:
- Tokenization -- Customer enters card in secure form; token generated client-side.
- Authorization -- RevKeen verifies the card can be charged for the requested amount.
- Capture -- Funds are captured and transferred (usually immediate).
- Confirmation -- Customer receives receipt, subscription/invoice updated.
Processing Payments via API
Create a One-Time Payment
const payment = await client.payments.create({
customerId: 'cus_xxxxxxxx',
amount: 9900, // $99.00 in cents
currency: 'USD',
paymentMethodToken: 'tok_xxxxxxxx',
description: 'Consulting fee',
metadata: {
orderId: 'order_12345',
},
});
if (payment.data.status === 'succeeded') {
console.log('Payment successful!');
console.log('Transaction ID:', payment.data.transactionId);
}Pay an Invoice
// Pay an existing invoice with saved payment method
const result = await client.invoices.pay('inv_xxxxxxxx');
// Or specify a different payment method
const result = await client.invoices.pay('inv_xxxxxxxx', {
paymentMethodId: 'pm_xxxxxxxx',
});
console.log('Invoice paid:', result.data.paidAt);Transaction Statuses
| Status | Description | Funds |
|---|---|---|
pending | Payment initiated, awaiting processing | Held |
succeeded | Payment completed successfully | Captured |
failed | Payment declined or error occurred | None |
requires_action | Additional verification needed (3DS) | Held |
refunded | Full amount returned to customer | Returned |
partially_refunded | Partial amount returned | Partial |
voided | Reversed before settlement | Released |
Handling Declines
When a payment fails, RevKeen provides detailed decline information:
| Category | Common Codes | Recommended Action |
|---|---|---|
| Insufficient Funds | 300, 301 | Ask customer to use different card or try later |
| Card Declined | 200, 204 | Card blocked by issuer -- request new card |
| Invalid Card | 303, 530 | Card number invalid -- re-enter card details |
| Expired Card | 202, 223 | Request updated card information |
| CVV Mismatch | 225 | Re-enter CVV -- potential fraud indicator |
| Limit Exceeded | 402, 521 | Card limit reached -- try smaller amount or different card |
try {
const payment = await client.payments.create({
customerId: 'cus_xxxxxxxx',
amount: 9900,
currency: 'USD',
paymentMethodToken: 'tok_xxxxxxxx',
});
} catch (error) {
if (error.code === 'payment_declined') {
console.log('Decline code:', error.declineCode);
console.log('Message:', error.message);
switch (error.declineCode) {
case '300':
case '301':
return 'Insufficient funds. Please try a different card.';
case '200':
return 'Card declined. Please contact your bank.';
default:
return 'Payment failed. Please try again.';
}
}
}3D Secure (3DS) Authentication
Some payments require additional verification through 3D Secure. RevKeen handles this automatically in the checkout flow:
- Payment initiated -- Gateway determines 3DS is required
- Customer redirected to bank's verification page
- Customer completes verification (password, SMS code, etc.)
- Customer redirected back -- Payment completes
3DS helps reduce fraud and shifts liability to the card issuer. It's required for Strong Customer Authentication (SCA) in the EU.
Reversing Payments: Void vs Refund
RevKeen provides intelligent payment reversal options based on settlement timing. Understanding when to use each method can save you significant processing fees.
How It Works
| Method | Timing | Processing Fees | Customer Impact |
|---|---|---|---|
| Void | Before daily settlement (typically before 8 PM ET) | No fees | Charge never appears on statement |
| Refund | After daily settlement | Original fees not returned | Shows as separate refund transaction |
Settlement Timing and Smart Warnings
RevKeen automatically tracks settlement timing for each payment gateway and provides real-time warnings to help you choose the best reversal method.
Safe to Void -- Settlement is 2+ hours away. Void will succeed with high confidence. This is the recommended option to avoid processing fees.
High-Risk Void Window -- Settlement is within 15 minutes. The batch may have already closed. If void fails, you will need to process a refund instead. The dashboard will show "Attempt Void" with a warning alert.
Settlement Complete -- Transaction has been settled. Void is no longer available. You must process a refund to return funds to the customer.
Smart Reversal Logic: RevKeen automatically determines eligibility based on your gateway's settlement schedule. When you view a payment, you'll see only the available options with clear warnings for high-risk scenarios.
Using the Dashboard
- Navigate to Invoice or Payment -- Go to Invoices, select invoice, click payment row actions menu.
- Choose Reversal Method -- The dialog will show available options based on settlement status. Review settlement timing information and any warnings displayed.
- Confirm and Execute -- Click the action button ("Void Payment", "Attempt Void", or "Process Refund") to execute the reversal.
Important: If a high-risk void fails because settlement already occurred, you will need to manually process a refund. The system cannot automatically fall back to refund due to accounting and tax implications.
Processing Refunds
// Full refund
const refund = await client.refunds.create({
transactionId: 'txn_xxxxxxxx',
});
// Partial refund
const partialRefund = await client.refunds.create({
transactionId: 'txn_xxxxxxxx',
amount: 2500, // Refund $25.00
});
// Refund with reason
const refund = await client.refunds.create({
transactionId: 'txn_xxxxxxxx',
reason: 'Customer request',
});Refunds typically take 5-10 business days to appear on the customer's statement. You cannot refund more than the original transaction amount.
Credit Notes
Credit notes are RevKeen's single reversal document. Instead of separate void, refund, and credit workflows, merchants issue credit notes against a paid invoice and RevKeen automatically routes the correct gateway operation (void, refund, terminal reversal, bank payout) based on the original payment's gateway, payment method, and context.
A credit note is always issued against a specific invoice -- it is the formal accounting record that reduces or reverses the amount owed on that invoice.
When to Use Credit Notes
- Invoice Corrections -- Wrong amount charged, billing error, or service not delivered as promised.
- Service Credits -- Goodwill credits, promotional adjustments, or compensation for service issues.
- Subscription Cancellations -- Prorate refunds when canceling subscriptions mid-period.
- Partial Refunds -- Return a portion of the invoice amount while keeping the invoice active.
- Voiding Unpaid Invoices -- A full credit note on an unpaid invoice automatically voids it.
Creating Credit Notes from the Dashboard
There are two ways to issue a credit note:
From an Invoice (most common):
- Go to Invoices and open a paid invoice.
- Click Issue Credit Note in the invoice actions.
- Choose full or partial amount, select a reason, and pick a credit method.
From the Customer page:
- Go to Customers and open a customer.
- Switch to the Credit Notes tab.
- Click Issue Credit Note -- this shows a list of the customer's paid invoices.
- Select the invoice you want to credit.
- Fill in the credit note details (amount, reason, credit method).
The Credit Notes tab also displays all existing credit notes for that customer with their current status (Processing, Refunded, Failed).
Credit Note Options
| Credit Method | Effect | Best For |
|---|---|---|
| Refund to Payment Method | Issues credit note and automatically processes the correct gateway reversal | Customer paid and wants money back |
| Customer Balance | Issues credit note and adds credit to customer account | Customer wants credit toward future purchases |
| Credit Note Only | Issues credit note for record-keeping only | Manual refund outside RevKeen or goodwill gesture |
Automatic Gateway Routing
When you select "Refund to Payment Method", you do not choose which gateway to use. RevKeen automatically determines the correct reversal operation based on how the original payment was made. The routing is fully automatic -- the system reads the payment's gateway from the transaction record and selects the best operation.
| Original Payment Method | What RevKeen Does Automatically |
|---|---|
| Card (online via NMI) | Void (if pre-settlement) or refund (if post-settlement) |
| Card (terminal / PAX) | Terminal reversal (same-day), terminal refund (card re-present), or NMI gateway-direct fallback if terminal is offline |
| Bank transfer (fire.com) | Cancel (if pending) or credit transfer payout to customer IBAN (if settled) |
| Customer balance | Instant ledger reversal (no gateway call needed) |
For terminal payments, RevKeen checks whether the terminal is reachable and whether the customer is present before choosing between a terminal-native reversal and a gateway-direct fallback. If the terminal is offline, the refund is processed through the payment processor without requiring the terminal.
You don't pick NMI vs Terminal vs Bank. RevKeen knows how the customer originally paid and routes accordingly. For invoices paid with multiple payments across different gateways, each payment is reversed through its own original gateway.
Multi-Payment Invoices (LIFO Allocation)
When an invoice was paid with multiple payments (for example, a partial card payment and a balance payment), RevKeen allocates the credit in last-in, first-out (LIFO) order. The most recent payment is reversed first, then the next most recent, until the full credit amount is allocated. Each payment is reversed through its own original gateway.
Multiple Credit Notes per Invoice
You can issue multiple credit notes against the same invoice. RevKeen validates that the total credited amount never exceeds the invoice total. When credit notes sum to the full invoice amount, the invoice is automatically marked as voided.
Intelligent Tax Handling
RevKeen automatically calculates proportional tax adjustments when issuing credit notes:
- Proportional Tax Credits -- Tax amounts are automatically calculated proportionally to the credited amount. For example, crediting 50% of an invoice also credits 50% of the tax.
- Penny-Perfect Chain Handling -- When issuing multiple credit notes against the same invoice, the final credit note automatically "sweeps" any remaining fractional pennies of tax. This prevents 1-2 cent discrepancies that can occur with rounding in credit note chains.
- Tax Provider Sync -- Credit notes automatically sync with your tax provider (Quaderno, TaxJar, etc.) to maintain accurate tax records and compliance reports.
Subscription Cancellation Protection
When issuing a credit note with subscription cancellation, RevKeen implements a safety guard: if you select "Refund to Payment Method" with subscription cancellation, the subscription will only cancel if the refund succeeds. This prevents scenarios where a customer loses access but didn't receive their refund due to gateway errors or expired payment methods.
If the refund fails, a warning is logged and the subscription remains active. You can then manually process the refund and cancel separately.
Notifications
When a credit note is issued, the following notifications are sent automatically:
- Merchant notification -- An in-app notification appears in the dashboard bell icon confirming the credit note was issued, including the amount and customer name.
- Customer notification -- An event is dispatched to the notifications service, which can deliver via email, SMS, or WhatsApp depending on your notification channel configuration in Settings > Notifications.
Note: Credit note email receipts and delivery channel selection (email, SMS, WhatsApp) per credit note are on the roadmap. Currently, customer notifications follow your global notification preferences.
Creating Credit Notes via API
// Issue credit note with automatic refund (gateway auto-routed)
const creditNote = await client.creditNotes.create({
invoiceId: 'inv_xxxxxxxx',
amount: 5000, // $50.00 in cents
reason: 'Service not delivered',
creditMethod: 'refund_to_payment_method',
cancelSubscription: true,
});
// Issue credit note with customer balance
const creditNote = await client.creditNotes.create({
invoiceId: 'inv_xxxxxxxx',
amount: 5000,
reason: 'Goodwill credit',
creditMethod: 'customer_balance',
});
// Credit note only (no financial movement)
const creditNote = await client.creditNotes.create({
invoiceId: 'inv_xxxxxxxx',
amount: 5000,
reason: 'Manual adjustment',
creditMethod: 'none',
});V2 API: Auto-Routing
When using the V2 API, pass auto_route: true to trigger multi-gateway reversal routing. For terminal (card-present) transactions, you can also specify customer_present to indicate whether the customer is physically at the terminal:
// V2 API with auto-routing
const response = await fetch('/v2/credit_notes', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk_live_xxxxxxxx',
'Content-Type': 'application/json',
},
body: JSON.stringify({
invoice_id: 'inv_xxxxxxxx',
amount_minor: 5000,
credit_method: 'refund_to_payment_method',
reason: 'Service not delivered',
auto_route: true, // Enable multi-gateway routing
customer_present: false, // Terminal: is customer at the device?
}),
});Audit Trail: All credit notes include reason codes, creator information, timestamp, gateway operation details, and links to associated refunds/voids. They appear on customer statements and integrate with your accounting system for complete financial reconciliation.
Payment Webhooks
Listen for payment events to keep your systems in sync:
| Event | Trigger |
|---|---|
payment.succeeded | Payment completed successfully |
payment.failed | Payment was declined |
payment.refunded | Refund processed |
payment.captured | Authorized payment captured |
payment.disputed | Chargeback received |
payment.requires_action | Additional customer action needed |
void.succeeded | Pre-settlement void completed |
void.failed | Void failed (transaction already settled) |
credit_note.created | Credit note issued against invoice |
credit_note.applied | Credit note reversal completed (refund/void processed) |
credit_note.voided | Credit note canceled or voided |
Best Practices
- Always Use Idempotency Keys -- Include an idempotency key with payment requests to prevent duplicate charges on retries.
- Handle Webhooks -- Don't rely solely on API responses. Use webhooks for reliable payment status updates.
- Store Transaction IDs -- Always store the transaction ID from successful payments for refunds and support inquiries.
- Graceful Error Handling -- Show user-friendly error messages and provide clear next steps when payments fail.
- Descriptive Statement Descriptors -- Use descriptive statement descriptors so customers recognize charges on their bank statements and reduce chargebacks.
Related
- Terminal Payments -- Accept card-present payments at a PAX terminal
- Dunning -- Automatic failed payment recovery
- Disputes -- Handle chargebacks and disputes
- Subscriptions -- Recurring billing guide