Payment Request
Understanding transaction status values is crucial for tracking payment progress and handling different transaction states in your integration.
Overview
Every transaction in the Peex Platform has a status that indicates its current state in the payment lifecycle. These statuses help you understand whether a payment is still processing, has completed successfully, or has encountered an issue.
Status Values
new
Transaction reached the PEEX Server and has been created successfully.
pending
The transaction has been paid, awaiting the confirmation identifier.
paid
Transaction has been PAID and CONFIRMED successfully.
failed
Automatic payment failed, reason is in the PAYMENT_PROOF field.
canceled
Transaction has been canceled manually, reason is in the PAYMENT_PROOF field.
rejected
Transaction has been rejected and the reason is mentioned in the response.
Detailed Status Information
| Status | Meaning | Next Action |
|---|---|---|
new | Transaction reached the PEEX Server | Monitor for status changes |
pending | Transaction has been paid, awaiting confirmation identifier | Wait for confirmation |
paid | Transaction has been PAID and CONFIRMED | Transaction complete |
failed | Automatic payment failed | Check PAYMENT_PROOF for reason |
canceled | Transaction canceled manually | Check PAYMENT_PROOF for reason |
rejected | Transaction rejected | Check response for reason |
Status Flow
The typical transaction flow follows this pattern:
graph TD
A[Payment Request Created] --> B[new]
B --> C[pending]
C --> D[paid]
B --> E[failed]
B --> F[rejected]
C --> G[canceled]
style B fill:#3b82f6,color:white
style C fill:#eab308,color:white
style D fill:#10b981,color:white
style E fill:#ef4444,color:white
style F fill:#f97316,color:white
style G fill:#6b7280,color:white
Normal Flow
- new → pending → paid ✅
- new → failed ❌
- new → rejected ❌
Special Cases
- pending → canceled (manual intervention)
- Direct to failed or rejected if validation fails
Monitoring Status
Polling Method
Status polling example
async function pollTransactionStatus(transactionId, maxAttempts = 30) {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
const response = await fetch(
`https://sandbox.peexit.com/api/v1/clients/all_requests?track_id=${transactionId}`,
{
headers: {
SECRETKEY: '37528871-1f6c-43e9-a74a-0ad1f4baba76',
'Content-Type': 'application/json',
},
},
)
if (response.ok) {
const data = await response.json()
const transaction = data[0] // Assuming single result
console.log(`Attempt ${attempt}: Status = ${transaction.status}`)
// Terminal states
if (
['paid', 'failed', 'canceled', 'rejected'].includes(
transaction.status,
)
) {
return {
status: transaction.status,
transaction: transaction,
completed: true,
}
}
// Continue polling for non-terminal states
if (attempt < maxAttempts) {
await new Promise((resolve) => setTimeout(resolve, 5000)) // Wait 5 seconds
}
} else {
console.error(`API Error: ${response.status}`)
break
}
} catch (error) {
console.error(`Polling attempt ${attempt} failed:`, error)
}
}
return {
status: 'unknown',
completed: false,
timeout: true,
}
}
// Usage
pollTransactionStatus('TXN-123456789').then((result) => {
if (result.completed) {
console.log(`Transaction completed with status: ${result.status}`)
} else {
console.log('Transaction status check timed out')
}
})
Webhook Method (Recommended)
Instead of polling, set up webhooks to receive real-time status updates:
Webhook handler example
// Express.js webhook endpoint
app.post('/webhook/peex-notifications', express.json(), (req, res) => {
const transactions = req.body // Array of transaction updates
transactions.forEach((transaction) => {
console.log(
`Transaction ${transaction.track_id} status: ${transaction.status}`,
)
switch (transaction.status) {
case 'paid':
handleSuccessfulPayment(transaction)
break
case 'failed':
handleFailedPayment(transaction)
break
case 'canceled':
handleCanceledPayment(transaction)
break
case 'rejected':
handleRejectedPayment(transaction)
break
default:
console.log(`Status ${transaction.status} - monitoring continues`)
}
})
res.status(200).send('OK') // Acknowledge receipt
})
function handleSuccessfulPayment(transaction) {
// Update your database
// Send confirmation to user
// Generate receipt
console.log(
`✅ Payment completed: ${transaction.amount} ${transaction.to_currency}`,
)
}
function handleFailedPayment(transaction) {
// Log failure reason
// Notify user of failure
// Optionally retry or refund
console.log(`❌ Payment failed: ${transaction.payment_proof}`)
}
Status-Based Actions
For new Status
- Monitor for status changes
- Set up timeout handling
- Prepare for next steps
For pending Status
- Continue monitoring
- Inform user payment is processing
- Avoid duplicate requests
For paid Status
- Complete transaction in your system
- Send confirmation to user
- Generate receipt/invoice
- Update account balances
For failed Status
- Parse failure reason from
payment_prooformessage - Notify user of failure
- Consider retry logic
- Process refunds if needed
For canceled Status
- Handle manual cancellation
- Notify relevant parties
- Process refunds
- Update transaction records
For rejected Status
- Review rejection reason
- Inform user of rejection
- Check compliance requirements
- Modify and resubmit if possible
Best Practices
- Always handle all status values in your code
- Set reasonable timeouts for status monitoring
- Use webhooks instead of polling when possible
- Log status changes for audit purposes
- Implement retry logic for failed transactions where appropriate
- Provide clear user feedback based on transaction status
Next Steps
Learn more about transaction monitoring and notifications: