Accepting Payments (PAYIN)
Learn how to accept payments from customers using local payment methods across Latin America.
What is PAYIN?
PAYIN is the order type used to accept payments from customers into your virtual balance account.
Use Cases
Accept payments for online purchases at checkout
Collect payments for services rendered
Recurring payments for subscriptions
Accept payments for issued invoices
How It Works
High-Level Flow
Customer initiates checkout
User adds items to cart and proceeds to payment
Your app creates PAYIN order
Send order details to Koywe API
Koywe returns payment URL
Receive a checkout URL for the customer
Customer completes payment
Customer is redirected to payment page and pays using their preferred method
Koywe confirms payment
Payment provider confirms and Koywe credits your virtual account
Your app receives webhook
You’re notified via webhook to fulfill the order
Detailed Flow Diagram
Supported Countries and Payment Methods
Colombia 🇨🇴
| Method | Type | Settlement Time |
|---|---|---|
| PSE | Bank transfer | Instant - 2 hours |
| Nequi | Mobile wallet | Instant |
Learn more about Colombian payment methods →
Brazil 🇧🇷
| Method | Type | Settlement Time |
|---|---|---|
| PIX | Instant payment | Instant |
Mexico 🇲🇽
| Method | Type | Settlement Time |
|---|---|---|
| SPEI | Bank transfer | Instant ⚡ |
Chile 🇨🇱
| Method | Type | Settlement Time |
|---|---|---|
| Khipu | Bank transfer | Instant - 2 hours |
Argentina 🇦🇷
| Method | Type | Settlement Time |
|---|---|---|
| Various | Local methods | Varies |
Prerequisites
Before integrating PAYIN orders, ensure you have:
Required:
- ✅ API Key and Secret
- ✅ Organization ID
- ✅ Merchant ID
- ✅ Understanding of Core Concepts
Recommended:
- Webhook endpoint configured
- Error handling implemented
- Testing in sandbox environment
Quick Start
Want to jump right in? Follow our step-by-step integration guide:
Detailed guide with code examples in cURL, Node.js, and Python
Or try the quickstart for a faster overview:
Create your first PAYIN order in minutes
Payment Flow Explained
Step-by-Step Process
1. Authentication
Obtain an access token using your API credentials.
const token = await authenticate(apiKey, secret);2. Get Available Payment Methods
Query which payment methods are available for the customer’s country.
const methods = await getPaymentMethods('CO', 'COP');
// Returns: PSE, NEQUI, etc.3. Create Contact (Optional but Recommended)
Store customer information for tracking and compliance.
const contact = await createContact({
email: 'customer@example.com',
fullName: 'Juan Pérez',
country: 'CO'
});4. Create PAYIN Order
Create the payment order with amount and payment method.
const order = await createPayinOrder({
amount: 50000,
currency: 'COP',
paymentMethod: 'PSE',
contactId: contact.id
});5. Redirect Customer
Send customer to the payment URL to complete payment.
window.location.href = order.paymentUrl;6. Handle Webhooks
Listen for webhook events to know when payment is complete.
// Webhook: order.completed
// -> Fulfill order, send confirmation emailOrder Status Progression
Understanding order statuses:
| Status | Description | Next Action |
|---|---|---|
| PENDING | Order created, waiting for customer | Customer needs to pay |
| PROCESSING | Payment being processed | Wait for confirmation |
| PAID | Payment confirmed | Funds being settled |
| COMPLETED | Funds in your account | Fulfill order |
| FAILED | Payment failed | Show error to customer |
| EXPIRED | Payment window expired | Create new order |
| CANCELLED | Order cancelled | No action needed |
Key Concepts
Payment URL
Every PAYIN order returns a paymentUrl:
{
"paymentUrl": "https://checkout.koywe.com/pay/ord_abc123"
}This URL:
- Is hosted by Koywe
- Provides a secure payment experience
- Handles the payment method UI
- Redirects back to your
successUrlorfailedUrl
Success and Failed URLs
Specify where to redirect customers after payment:
{
"successUrl": "https://yoursite.com/payment/success",
"failedUrl": "https://yoursite.com/payment/failed"
}Best Practice: Don’t rely solely on these redirects for order fulfillment. Always use webhooks as the source of truth.
External ID (Idempotency)
Use externalId to link orders to your system and prevent duplicates:
{
"externalId": "order-12345" // Your internal order ID
}Benefits:
- Safe to retry failed API calls
- Prevents duplicate charges
- Easy reconciliation with your database
Common Integration Patterns
Pattern 1: Simple Checkout
// 1. User clicks "Pay"
// 2. Create order
const order = await createPayinOrder({
amount: cartTotal,
currency: 'COP',
paymentMethod: 'PSE'
});
// 3. Redirect
window.location.href = order.paymentUrl;
// 4. Handle webhook
// 5. Fulfill orderPattern 2: Payment Method Selection
// 1. Show available methods
const methods = await getPaymentMethods(country, currency);
// 2. User selects method
// 3. Create order with selected method
const order = await createPayinOrder({
amount: cartTotal,
currency: 'COP',
paymentMethod: userSelectedMethod
});
// 4. Redirect and handle webhookPattern 3: Stored Customer
// 1. Check if customer exists
let contact = await findContact(email);
if (!contact) {
contact = await createContact(customerData);
}
// 2. Create order linked to contact
const order = await createPayinOrder({
amount: cartTotal,
contactId: contact.id,
// ... other fields
});
// 3. Track payment history per contactNext Steps
Step-by-step implementation with code examples
Detailed guide to each payment method by country
Common issues and how to resolve them
Test payment flows in sandbox environment