Payments Guide
This guide covers everything you need to know about creating and managing payments through the LuxCore API.
Payment Types
LuxCore supports four payment types:
Type Direction Description depositInbound Customer pays to merchant (checkout) withdrawalOutbound Merchant pays to customer/vendor (payout) deposit_ppInbound Deposit with hosted payment page withdrawal_ppOutbound Withdrawal with hosted payment page
Payment Methods
Method Code Deposit Withdrawal Processing Time SPEI spei✅ ✅ Up to 30 min OXXO oxxo✅ ❌ Up to 30 min Card card✅ ❌ Up to 30 min Bank Transfer bank_transfer✅ ✅ Up to 30 min Cash cash✅ ❌ Up to 30 min Crypto crypto✅ ✅ Up to 30 min PayID payid✅ ✅ Up to 10 min iPay ipay✅ ❌ Instant (redirect)
Creating a Deposit (Customer Payment)
When a customer needs to pay you:
ARS (Argentina)
MXN (Mexico)
UYU (Uruguay)
AUD (Australia)
LKR (Sri Lanka)
curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 150000,
"currency": "ARS",
"method": "bank_transfer",
"type": "deposit",
"merchant_reference": "order_abc123",
"description": "Order #ABC123",
"customer": {
"name": "Maria Garcia",
"email": "maria@example.com",
"phone": "+5491112345678"
},
"metadata": {
"order_id": "abc123",
"source": "web"
}
}'
Response (ARS) {
"transaction_id" : "pay_1234567890_abcdefgh" ,
"status" : "processing" ,
"amount" : 150000 ,
"currency" : "ARS" ,
"method" : "bank_transfer" ,
"type" : "deposit" ,
"fee_amount" : 6750 ,
"net_amount" : 143250 ,
"bank_details" : {
"amount" : "150000" ,
"purpose" : "Payment pay_1234567890_abcdefgh" ,
"currency" : "ARS" ,
"bank_name" : "Banco Nacion" ,
"swift_code" : null ,
"account_holder" : "LuxCore Platform S.A." ,
"account_number" : "0110012345678901234567"
},
"created_at" : "2025-01-21T10:30:00Z" ,
"expires_at" : "2025-01-21T10:45:00Z"
}
curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 150000,
"currency": "MXN",
"method": "spei",
"type": "deposit",
"merchant_reference": "order_abc123",
"description": "Order #ABC123",
"customer": {
"name": "Maria Garcia",
"email": "maria@example.com",
"phone": "+525551234567"
},
"metadata": {
"order_id": "abc123",
"source": "web"
}
}'
Response (MXN) {
"transaction_id" : "pay_1234567890_abcdefgh" ,
"status" : "processing" ,
"amount" : 150000 ,
"currency" : "MXN" ,
"method" : "spei" ,
"type" : "deposit" ,
"fee_amount" : 6750 ,
"net_amount" : 143250 ,
"bank_details" : {
"amount" : "150000" ,
"purpose" : "Payment pay_1234567890_abcdefgh" ,
"currency" : "MXN" ,
"bank_name" : "STP" ,
"swift_code" : null ,
"account_holder" : "LuxCore Platform S.A. de C.V." ,
"account_number" : "646180157000000001"
},
"created_at" : "2025-01-21T10:30:00Z" ,
"expires_at" : "2025-01-21T10:45:00Z"
}
curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 150000,
"currency": "UYU",
"method": "bank_transfer",
"type": "deposit",
"merchant_reference": "order_abc123",
"description": "Order #ABC123",
"customer": {
"name": "Maria Garcia",
"email": "maria@example.com",
"phone": "+59891234567"
},
"metadata": {
"order_id": "abc123",
"source": "web"
}
}'
Response (UYU) {
"transaction_id" : "pay_1234567890_abcdefgh" ,
"status" : "processing" ,
"amount" : 150000 ,
"currency" : "UYU" ,
"method" : "bank_transfer" ,
"type" : "deposit" ,
"fee_amount" : 6750 ,
"net_amount" : 143250 ,
"bank_details" : {
"amount" : "150000" ,
"purpose" : "Payment pay_1234567890_abcdefgh" ,
"currency" : "UYU" ,
"bank_name" : "BROU" ,
"swift_code" : null ,
"account_holder" : "LuxCore Platform S.A." ,
"account_number" : "001234567890"
},
"created_at" : "2025-01-21T10:30:00Z" ,
"expires_at" : "2025-01-21T10:45:00Z"
}
cURL (Bank Transfer)
Python (Bank Transfer)
curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 150000,
"currency": "AUD",
"method": "bank_transfer",
"type": "deposit",
"merchant_reference": "order_abc123",
"description": "Order #ABC123",
"customer": {
"name": "James Smith",
"email": "james@example.com",
"phone": "+61412345678"
},
"metadata": {
"order_id": "abc123",
"source": "web"
}
}'
Response (AUD - Bank Transfer) {
"transaction_id" : "pay_1234567890_abcdefgh" ,
"status" : "processing" ,
"amount" : 150000 ,
"currency" : "AUD" ,
"method" : "bank_transfer" ,
"type" : "deposit" ,
"fee_amount" : 6750 ,
"net_amount" : 143250 ,
"bank_details" : {
"amount" : "150000" ,
"purpose" : "Payment pay_1234567890_abcdefgh" ,
"currency" : "AUD" ,
"bank_name" : "Commonwealth Bank" ,
"swift_code" : "CTBAAU2S" ,
"account_holder" : "LuxCore Platform Pty Ltd" ,
"bsb" : "062-000" ,
"account_number" : "12345678"
},
"created_at" : "2026-02-18T10:30:00Z" ,
"expires_at" : "2026-02-18T10:45:00Z"
}
Alternatively, use PayID for a faster deposit experience: cURL (PayID)
Python (PayID)
curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 150000,
"currency": "AUD",
"method": "payid",
"type": "deposit",
"merchant_reference": "order_abc123",
"description": "Order #ABC123",
"customer": {
"name": "James Smith",
"email": "james@example.com",
"phone": "+61412345678"
},
"metadata": {
"order_id": "abc123",
"source": "web"
}
}'
Response (AUD - PayID) {
"transaction_id" : "pay_1234567890_abcdefgh" ,
"status" : "processing" ,
"amount" : 150000 ,
"currency" : "AUD" ,
"method" : "payid" ,
"type" : "deposit" ,
"fee_amount" : 6750 ,
"net_amount" : 143250 ,
"payid_details" : {
"amount" : "150000" ,
"purpose" : "Payment pay_1234567890_abcdefgh" ,
"currency" : "AUD" ,
"payid" : "pay-1234567890@lux-core.io" ,
"payid_type" : "email" ,
"payid_name" : "LuxCore Platform Pty Ltd" ,
"reference" : "LXC-ABC123"
},
"created_at" : "2026-02-18T10:30:00Z" ,
"expires_at" : "2026-02-18T10:40:00Z"
}
PayID uses Australia’s New Payments Platform (NPP) for near-instant settlement. The customer sends funds to the provided PayID identifier (email, phone, or ABN) through their banking app. PayID deposits typically settle within minutes.
curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 150000,
"currency": "LKR",
"method": "ipay",
"type": "deposit",
"merchant_reference": "order_abc123",
"description": "Order #ABC123",
"customer": {
"name": "Kamal Perera",
"email": "kamal@example.com",
"phone": "+94771234567"
},
"metadata": {
"order_id": "abc123",
"source": "web"
}
}'
Response (LKR) {
"transaction_id" : "pay_1234567890_abcdefgh" ,
"status" : "processing" ,
"amount" : 150000 ,
"currency" : "LKR" ,
"method" : "ipay" ,
"type" : "deposit" ,
"fee_amount" : 6750 ,
"net_amount" : 143250 ,
"redirect_url" : "https://checkout.lux-core.io/pay/abc123?sig=...&exp=..." ,
"created_at" : "2025-11-22T10:30:00Z" ,
"expires_at" : "2025-11-22T10:45:00Z"
}
Optionally, restrict the checkout to a specific payment scheme: curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 150000,
"currency": "LKR",
"method": "ipay",
"type": "deposit",
"merchant_reference": "order_visa_only",
"customer": {
"name": "Kamal Perera",
"email": "kamal@example.com"
},
"ipay": {
"payment_method": "VISA"
}
}'
Available payment schemes for iPay:
VISA — Visa cards
MC — Mastercard
IPAY — iPay App
LQR — LankaQR (scan-to-pay)
Pass ipay.payment_method to restrict the checkout to a single scheme. If omitted, all available schemes are shown to the customer. iPay deposits use a redirect-based flow . After creating the payment, redirect the customer to the redirect_url returned in the response. The customer completes payment on the hosted checkout page, and status updates are delivered via webhooks.
iPay Integration Details Redirect Flow
Create a payment via POST /payments with method: "ipay" and currency: "LKR"
The response includes a redirect_url — redirect the customer’s browser to this URL
The customer completes payment on the iPay hosted checkout page (Visa, Mastercard, LankaQR, or iPay App)
iPay sends a server-to-server callback to confirm payment status
You receive a webhook (payment.completed or payment.failed) with the final status
Response Fields Field Type Description redirect_urlstring URL to redirect the customer for payment statusstring Initial status is processing fee_amountinteger Calculated fee in minor units net_amountinteger Amount after fee deduction expires_atstring Payment expiration timestamp (ISO 8601)
Limits Parameter Value Minimum amount 100 (Rs. 1.00 LKR) Currency LKR only Withdrawals Not supported
iPay Callback Statuses iPay reports three transaction statuses via server-to-server callback: iPay Status Code LuxCore Status Description Accepted AcompletedPayment successful, funds transferred Pending PprocessingFunds deducted, transfer pending (end-of-day settlement) Declined DfailedPayment declined by iPay or card issuer
Pending (P) status: In rare cases, iPay may report a “Pending” status, meaning the customer’s funds have been deducted but the transfer to the merchant is scheduled for end-of-day batch settlement. The system monitors these payments and auto-cancels them if unresolved after 24 hours.
Creating a Withdrawal (Payout)
To send money to a beneficiary:
customer vs payout: For withdrawals, both objects refer to the same person — the recipient of the funds.
customer — personal contact information (name, email, phone). Used for customer identification, matching, and communication.
payout — bank account details for executing the transfer (account number, bank code, reference).
Payout Fields
Field Required Description Example recipient_nameYes Full name of the beneficiary (must match bank account holder) "Juan Perez Martinez"bank_accountYes Bank account number. CBU/CVU (22 digits) for ARS, CLABE (18 digits) for MXN, account number for UYU, account number (6-10 digits) for AUD "0110012345678901234567"bank_codeNo Bank code. Required for MXN/SPEI. For AUD, use BSB (6 digits, format XXX-XXX) "002"account_typeNo Account type "checking"beneficiary_tax_idNo Beneficiary tax ID (RFC, RUC, CUIT, ABN) "20-12345678-9"descriptionNo Purpose of the payout "Salary January 2025"referenceNo Merchant-provided tracking reference. If not provided, system generates one automatically "PAYOUT-JAN-001"payidNo PayID identifier (email, phone, or ABN). Required when method is payid for AUD withdrawals "james@example.com"payid_typeNo Type of PayID: email, phone, or abn. Required when payid is provided "email"
ARS (Argentina)
MXN (Mexico)
UYU (Uruguay)
AUD (Australia)
curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 250000,
"currency": "ARS",
"method": "bank_transfer",
"type": "withdrawal",
"merchant_reference": "payout_vendor_001",
"description": "Payout January 2025",
"customer": {
"name": "Juan Perez Martinez",
"email": "juan.perez@example.com",
"phone": "+5491112345678"
},
"payout": {
"recipient_name": "Juan Perez Martinez",
"bank_account": "0110012345678901234567"
}
}'
Response (ARS Withdrawal) {
"transaction_id" : "pay_1234567890_abcdefgh" ,
"status" : "pending" ,
"amount" : 250000 ,
"currency" : "ARS" ,
"method" : "bank_transfer" ,
"type" : "withdrawal" ,
"merchant_reference" : "payout_vendor_001" ,
"payout" : {
"recipient_name" : "Juan Perez Martinez" ,
"bank_account" : "0110012345678901234567" ,
"status" : "pending"
},
"created_at" : "2025-01-21T10:30:00Z"
}
curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 250000,
"currency": "MXN",
"method": "spei",
"type": "withdrawal",
"merchant_reference": "payout_vendor_001",
"description": "Payout January 2025",
"customer": {
"name": "Juan Perez Martinez",
"email": "juan.perez@example.com",
"phone": "+525551234567"
},
"payout": {
"recipient_name": "Juan Perez Martinez",
"bank_account": "012345678901234567",
"bank_code": "002",
"reference": "PAYOUT-JAN-001"
}
}'
Response (MXN Withdrawal) {
"transaction_id" : "pay_1234567890_abcdefgh" ,
"status" : "pending" ,
"amount" : 250000 ,
"currency" : "MXN" ,
"method" : "spei" ,
"type" : "withdrawal" ,
"merchant_reference" : "payout_vendor_001" ,
"payout" : {
"recipient_name" : "Juan Perez Martinez" ,
"clabe" : "012345678901234567" ,
"bank_code" : "002" ,
"status" : "pending"
},
"created_at" : "2025-01-21T10:30:00Z"
}
curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 250000,
"currency": "UYU",
"method": "bank_transfer",
"type": "withdrawal",
"merchant_reference": "payout_vendor_001",
"description": "Payout January 2025",
"customer": {
"name": "Juan Perez Martinez",
"email": "juan.perez@example.com",
"phone": "+59891234567"
},
"payout": {
"recipient_name": "Juan Perez Martinez",
"bank_account": "001234567890"
}
}'
Response (UYU Withdrawal) {
"transaction_id" : "pay_1234567890_abcdefgh" ,
"status" : "pending" ,
"amount" : 250000 ,
"currency" : "UYU" ,
"method" : "bank_transfer" ,
"type" : "withdrawal" ,
"merchant_reference" : "payout_vendor_001" ,
"payout" : {
"recipient_name" : "Juan Perez Martinez" ,
"bank_account" : "001234567890" ,
"status" : "pending"
},
"created_at" : "2025-01-21T10:30:00Z"
}
cURL (Bank Transfer)
Python (Bank Transfer)
curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 250000,
"currency": "AUD",
"method": "bank_transfer",
"type": "withdrawal",
"merchant_reference": "payout_vendor_001",
"description": "Payout February 2026",
"customer": {
"name": "James Smith",
"email": "james@example.com",
"phone": "+61412345678"
},
"payout": {
"recipient_name": "James Smith",
"bank_account": "12345678",
"bank_code": "062-000"
}
}'
Response (AUD Bank Transfer Withdrawal) {
"transaction_id" : "pay_1234567890_abcdefgh" ,
"status" : "pending" ,
"amount" : 250000 ,
"currency" : "AUD" ,
"method" : "bank_transfer" ,
"type" : "withdrawal" ,
"merchant_reference" : "payout_vendor_001" ,
"payout" : {
"recipient_name" : "James Smith" ,
"bank_account" : "12345678" ,
"bsb" : "062-000" ,
"status" : "pending"
},
"created_at" : "2026-02-18T10:30:00Z"
}
Alternatively, use PayID for faster payouts: cURL (PayID)
Python (PayID)
curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 250000,
"currency": "AUD",
"method": "payid",
"type": "withdrawal",
"merchant_reference": "payout_vendor_001",
"description": "Payout February 2026",
"customer": {
"name": "James Smith",
"email": "james@example.com",
"phone": "+61412345678"
},
"payout": {
"recipient_name": "James Smith",
"payid": "james@example.com",
"payid_type": "email"
}
}'
Response (AUD PayID Withdrawal) {
"transaction_id" : "pay_1234567890_abcdefgh" ,
"status" : "pending" ,
"amount" : 250000 ,
"currency" : "AUD" ,
"method" : "payid" ,
"type" : "withdrawal" ,
"merchant_reference" : "payout_vendor_001" ,
"payout" : {
"recipient_name" : "James Smith" ,
"payid" : "james@example.com" ,
"payid_type" : "email" ,
"status" : "pending"
},
"created_at" : "2026-02-18T10:30:00Z"
}
PayID Withdrawal Types:
email — recipient’s email registered as PayID (e.g., james@example.com)
phone — recipient’s phone number in E.164 format (e.g., +61412345678)
abn — Australian Business Number (e.g., 51824753556)
Withdrawals require sufficient balance in your merchant account. Use the Balance API to check available funds before initiating payouts.
Per-Payment Webhook URL
You can optionally specify a webhook_url to receive events for a specific payment without pre-configuring a webhook endpoint:
curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 150000,
"currency": "ARS",
"method": "bank_transfer",
"type": "deposit",
"merchant_reference": "order_abc123",
"customer": {
"name": "Maria Garcia",
"email": "maria@example.com"
},
"webhook_url": "https://your-server.com/webhooks/payments",
"webhook_events": ["payment.completed", "payment.failed"]
}'
Field Type Required Description webhook_urlstring No HTTPS URL to receive webhook events for this payment (max 2048 characters) webhook_eventsstring[] No Events to subscribe to. Defaults to ["payment.created", "payment.completed", "payment.failed", "payment.refunded"]
In-request webhooks are signed using your merchant’s default webhook secret . See the Webhooks Guide for details on signature verification and secret management.
Hosted Payment Pages
For a simpler integration, use hosted payment pages (deposit_pp or withdrawal_pp):
curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 100000,
"currency": "ARS",
"method": "bank_transfer",
"type": "deposit_pp",
"merchant_reference": "checkout_123",
"customer": {
"name": "Customer Name",
"email": "customer@example.com"
}
}'
Response includes a payment page URL:
{
"transaction_id" : "pay_xyz789" ,
"status" : "processing" ,
"payment_page" : {
"url" : "https://{payment-page-host}/pay/{token}?sig={signature}&exp={expires}"
}
}
The payment page URL is dynamically generated and may vary based on the selected currency, payment method, and region. Always use the exact URL returned in the API response.
Redirect your customer to this URL to complete the payment.
Payment Statuses
Understanding payment statuses is crucial for proper integration. Each status represents a specific state in the payment lifecycle.
Status Reference
Status Description Terminal Webhooks Sent pendingPayment created, awaiting processing or approval ❌ - processingPayment is being processed, awaiting customer action ❌ - completedPayment was successful, funds transferred ✅ payment.completedfailedPayment failed due to error or rejection ✅ payment.failedcancelledPayment was cancelled by merchant or system ✅ payment.cancelledexpiredPayment expired before completion ✅ payment.failedrefundedPayment was fully refunded ✅ payment.refundedpartial_refundPayment was partially refunded ✅ payment.refunded
Terminal statuses (completed, failed, cancelled, expired, refunded, partial_refund) are final states - the payment cannot transition to non-terminal status.
Initial Status by Payment Type
Payment Type Initial Status Description depositprocessingCustomer needs to complete the transfer withdrawalpendingAwaiting approval and processing deposit_ppprocessingCustomer redirected to payment page withdrawal_pppendingAwaiting approval
Status Descriptions
The payment has been created and is waiting to be processed. For withdrawals, this means the payout is queued and awaiting approval or processing by the payment provider. Next possible statuses: processing, cancelled, expired
The payment is actively being processed. For deposits, this means the customer has been given payment instructions (bank details, payment page URL) and we are waiting for them to complete the transfer. Next possible statuses: completed, failed, cancelled, expired
The payment was successful. For deposits, the funds have been received and credited to your merchant balance. For withdrawals, the funds have been sent to the beneficiary. This is a terminal status. You will receive a payment.completed webhook.
The payment could not be completed. This can happen due to various reasons: bank rejection, invalid account details, insufficient funds (for withdrawals), or technical issues. This is a terminal status. You will receive a payment.failed webhook with an error_code and error_message.
The payment was cancelled before completion. This can be initiated by the merchant via API, by an admin, or automatically by the system. This is a terminal status. You will receive a payment.cancelled webhook.
The payment was not completed within the allowed time window. Deposits typically expire after 1-60 minutes (configurable per merchant). This is a terminal status. You will receive a payment.failed webhook with error_code: TTL_EXPIRED.
The payment was fully refunded after completion. The refunded amount has been deducted from your merchant balance. This is a terminal status. You will receive a payment.refunded webhook.
The payment was partially refunded. Part of the original amount has been returned to the customer. This is a terminal status. You will receive a payment.refunded webhook with the refunded amount.
Handling Status Changes
Always use webhooks to track payment status changes. Polling the API is not recommended as it adds latency and may hit rate limits.
// Example: Handling status in your webhook handler
switch ( payment . status ) {
case 'completed' :
// Update order to paid, deliver goods/services
await markOrderAsPaid ( payment . merchant_reference );
break ;
case 'failed' :
case 'expired' :
// Notify customer, allow retry
await notifyPaymentFailed ( payment . merchant_reference , payment . error_message );
break ;
case 'cancelled' :
// Clean up pending order
await cancelOrder ( payment . merchant_reference );
break ;
case 'refunded' :
case 'partial_refund' :
// Process refund in your system
await processRefund ( payment . merchant_reference , payment . refunded_amount );
break ;
}
Retrieving Payment Status
curl -X GET "https://api.lux-core.io/api/v1/payments/pay_1234567890_abcdefgh" \
-H "X-API-Key: qp_test_your_key"
Listing Payments
curl -X GET "https://api.lux-core.io/api/v1/payments?status=completed&limit=20" \
-H "X-API-Key: qp_test_your_key"
Query Parameters
Parameter Type Description statusstring Filter by status methodstring Filter by payment method created_at_fromISO 8601 Start date filter created_at_toISO 8601 End date filter limitinteger Results per page (max 100) offsetinteger Pagination offset
Customer Management
Payments are automatically linked to customers in your account. You can optionally pass an existing customer ID to link a payment to a specific customer.
Customer Fields
Field Type Required Description namestring No Customer full name (max 255 characters) emailstring No Customer email address (max 255 characters) phonestring No Customer phone number (max 50 characters) external_idstring No Your unique customer identifier from your system. Used to link payments to your internal customer records
external_id is your own customer reference (e.g., user ID from your database). It is stored on the customer record and is unique per merchant. Use it for reconciliation and analytics without relying on LuxCore internal IDs.
Automatic Customer Matching
When creating a payment, if you don’t provide a customer_id, the system will:
Search for an existing customer by email (exact match, case-insensitive)
If not found by email, search by phone (normalized)
If no match found, create a new customer with the provided data
If external_id is provided and a customer is found by email or phone, the external_id will be assigned to the existing customer (if not already set).
Using External ID
Pass external_id inside the customer object to link payments to your internal customer records:
curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 150000,
"currency": "ARS",
"method": "bank_transfer",
"type": "deposit",
"merchant_reference": "order_abc123",
"customer": {
"name": "Maria Garcia",
"email": "maria@example.com",
"external_id": "usr_98765"
}
}'
external_id must be unique per merchant. If you attempt to create a new customer with an external_id that is already assigned to another customer within the same merchant account, the request will fail.
Using Customer ID
If you have an existing customer, you can pass their ID directly:
curl -X POST "https://api.lux-core.io/api/v1/payments" \
-H "X-API-Key: qp_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 150000,
"currency": "ARS",
"method": "bank_transfer",
"type": "deposit",
"merchant_reference": "order_abc123",
"customer_id": 12345,
"customer": {
"name": "Maria Garcia",
"email": "maria@example.com"
}
}'
When customer_id is provided, the system validates that the customer exists and belongs to your merchant account. The customer object fields (name, email, phone, external_id) are not updated in this case — only the link to the existing customer is used.
Customer in Response
Payment responses now include customer information:
{
"transaction_id" : "pay_1234567890_abcdefgh" ,
"status" : "processing" ,
"customer_id" : 12345 ,
"customer" : {
"id" : 12345 ,
"name" : "Maria Garcia" ,
"email" : "maria@example.com" ,
"phone" : "+5491112345678" ,
"external_id" : "usr_98765"
}
}
Cancelling a Payment
Cancel a pending payment:
curl -X POST "https://api.lux-core.io/api/v1/payments/pay_1234567890_abcdefgh/cancel" \
-H "X-API-Key: qp_test_your_key"
Only payments in pending status can be cancelled.
Idempotency
Use unique merchant_reference values for idempotency. If you submit a payment with a reference that was already used, the API will return the existing payment instead of creating a duplicate.
Best Practices
Validate Amounts Always validate amounts before submission. Amounts are in minor units (centavos).
Handle Webhooks Don’t rely on polling. Set up webhooks for real-time status updates.
Store References Save transaction_id and merchant_reference for reconciliation.
Check Balance For withdrawals, verify sufficient balance before initiating.