Collection API · Guide
Building your own checkout: a guide to payment collection APIs
A payment collection API lets your own website or app take payments while you design every screen. Your server asks for a payment, the customer completes one step (approving in their UPI app, authenticating a card, logging in to their bank), and the result comes back to you. This guide explains that flow from zero: the parties involved, how a payment moves from request to result, why "pending" is normal, how webhooks and safe retries work, and what to get right before going live. It stays at the level of concepts; exact endpoints and field names come with the API reference.
checkout · order 7731 · ₹1,499 (conceptual)
- 1Step 1, Customer's device to Your server: Customer places order 7731 and chooses to pay
- 2Step 2, Your server to Peneu: Create a payment: ₹1,499, your reference 7731, a unique idempotency key
- 3Step 3, Peneu to Your server: Payment created, status pending, with the customer's next step
- 4Step 4, Your server to Customer's device: Show the next step: open the UPI app, a card page or the bank's page
- 5Step 5, Customer's device to Provider and bank: Customer approves in their UPI app or with their bank
- 6Step 6, Provider and bank to Peneu: The bank's result comes back
- 7Step 7, Peneu to Your server: Notification: the payment's status changed
- 8Step 8, Your server to Peneu: Your server fetches the payment to confirm: succeeded
- 9Step 9, Your server to Customer's device: Order 7731 confirmed to the customer
If step 2 times out
- Send the same create request again with the same idempotency key: you get the original payment back, not a second one.
- Never generate a new key for a retry of the same attempt; that is how duplicate payments are created.
Chapter 01
What a collection API is
Every online payment needs a payment screen. You can use one that's provided for you, a hosted checkout, or build your own inside your website or app. A collection API is what makes the second option possible: your server asks for a payment, your screens guide the customer, and the API tells you how it ended.
Building your own checkout gives you control over the look, the flow and the data. It also makes you responsible for handling the awkward moments well: the customer who closes the app mid-payment, the bank that takes a minute to answer, the network timeout on your side.
You want the payment step inside your own app or site, in your design
A collection API
You want to go live quickly without building payment screens
You bill customers by invoice or message
Customers pay in person at a counter
Chapter 02
Who does what
Four parties take part in every API payment. The most important rule sits between the first two: anything secret, such as API keys and the decision to fulfil an order, stays on your server, never in the browser or the app.
- 01Customer's device
Shows your checkout; the customer approves the payment
- 02Your server
Holds your keys, creates payments, confirms the result, fulfils the order
- 03Peneu
One API across connected providers: routes, tracks status, notifies you
- 04Provider and bank
Process the payment and return the result
| Runs on | Should do | Should never do |
|---|---|---|
| The customer's device | Show the checkout and the next step | Hold API keys, or decide an order is paid |
| Your server | Create payments, receive notifications, confirm status, fulfil orders | Log full card numbers or secrets |
Chapter 03
The request-to-payment lifecycle
A payment created through an API moves through a small number of states. Most of its life is spent waiting for the customer or the bank, which is why the states in the middle matter as much as the ones at the end.
- created
Your server asked for the payment; nothing has been paid.
- pending
Waiting for the customer to act, or for the bank to confirm.
- succeeded
The payment is confirmed. Fulfil the order.
- failed ← from pending
Declined, abandoned or timed out, with a reason. The customer can try again as a new attempt.
- refunded ← from succeeded
Money returned later, in full or in part, as a refund.
Chapter 04
The customer's next step, by method
After your server creates a payment, the customer has one thing left to do, and what it is depends on the payment method. Your checkout's job is to show that step clearly and then wait. Which methods you can offer depends on what's enabled for your account.
| Method | The customer's next step | What your checkout should do |
|---|---|---|
| UPI on a phone | Their UPI app opens; they approve with their PIN | Show a waiting screen, then the result |
| UPI on a desktop | They scan a QR with their phone and approve | Show the QR and wait; don't ask them to refresh |
| Card | They may authenticate with their bank, e.g. a one-time password | Let the bank's step complete, then show the result |
| Netbanking | They log in to their bank and approve | Wait for them to return; confirm the result from your server |
How these methods compare, and where each tends to fail: how online payments work.
Chapter 05
Responses, pending and status checks
Creating a payment returns an answer straight away, but not the result, because the customer hasn't paid yet. The result arrives later, asynchronously. There are two ways to learn it: the platform notifies your server (a webhook), or your server asks for the payment's current status.
Use both. Notifications are fast and cheap; status checks are the safety net when a notification is late or lost. Check with increasing gaps, not in a tight loop, and stop once the payment reaches a final state.
The redirect isn't the result
Chapter 06
Webhooks
A webhook is a message the payment platform sends to an address on your server when something changes: a payment succeeded, failed or was refunded. It's how most integrations hear about results. Webhooks are delivered over the open internet, so a well-built receiver treats each one with care.
Delivery isn't perfect in any system: messages can arrive late, twice, or out of order, and deliveries that your server doesn't acknowledge are usually retried. Design for all of that from the start. See how Peneu normalises events across providers: unified webhooks.
| Step | What to do | Why |
|---|---|---|
| Verify | Check the notification's signature using the scheme in the API reference, and reject stale ones | Anyone can send a request to a public address |
| Deduplicate | Record each event's ID; ignore one you've already processed | The same event can be delivered more than once |
| Confirm | Fetch the payment's current status before changing your records | Events can arrive out of order |
| Acknowledge | Respond quickly with success, and do slow work afterwards | Slow responses look like failures and trigger retries |
| Monitor | Alert when notifications stop arriving or keep failing | A silent receiver means orders stuck as unpaid |
Chapter 07
Idempotency and safe retries
Networks fail at the worst moment. Your server sends "create a payment", the connection drops, and you don't know whether the payment was created. Sending the request again might create a second one. Idempotency solves this: you attach a unique key to the request, and repeating the request with the same key returns the original result instead of creating something new.
The pattern is widely used in payment APIs. How Peneu supports it, including the header or field and how long a key is remembered, is set out in the API reference.
| Situation | What to do |
|---|---|
| Your create request timed out | Send it again with the same idempotency key |
| The payment failed | Start a new attempt with a new key, after the customer chooses to try again |
| The payment is pending | Don't create another payment; wait for the result or check its status |
| The customer clicked 'Pay' twice | Use one key per checkout attempt, so both clicks map to one payment |
Chapter 08
Handling errors
Payment errors fall into a few families. The family, not the individual code, decides what you show the customer and whether a retry makes sense. Map each family to a clear customer message once, and log the technical detail for your own team.
| Family | Examples | Show the customer | Retry? |
|---|---|---|---|
| Customer | Wrong PIN, insufficient balance, cancelled in the app | What happened, and an option to try again | Yes, as a new attempt |
| Bank or issuer | Declined by the bank, card not enabled for online use | Your bank declined it; try another card or method | With another method |
| Network or provider | Timeout, provider temporarily unavailable | Something went wrong; you haven't been charged twice | After a status check |
| Your integration | Invalid amount, missing field, authentication failed | A generic apology; alert your team | Not until it's fixed |
Chapter 09
Security
Owning the checkout doesn't mean owning sensitive data. A few rules keep an API integration safe and keep your security obligations small.
| Rule | Why |
|---|---|
| Keep API keys on your server; use separate keys for test and live | A leaked key in an app or web page can be used by anyone |
| Let the provider's secure fields or page collect card details | Raw card numbers never touch your systems, which keeps your security scope small |
| Verify every notification before trusting it | Forged notifications are an easy way to fake a payment |
| Decide 'paid' only on your server, from a confirmed status | The browser and app can be tampered with |
| Never log full card numbers, PINs, OTPs or secrets | Logs are copied, shared and kept for years |
| Rotate keys when people leave or a key may have been exposed | Old keys are a quiet risk |
Chapter 10
Testing and going live
Most integrations are tested only on the happy path, and most production incidents happen on the others. Test against a sandbox where one is available for your account, and make the failures part of the plan.
| Check | Done when |
|---|---|
| Success on every method you offer | The order is fulfilled only after your server confirms the status |
| Failure and abandonment | The customer sees a clear message and can try again |
| Pending for a long time | The checkout waits, and your server resolves it by notification or status check |
| Duplicate and out-of-order notifications | They change nothing the second time |
| A timed-out create request | Retrying with the same key returns the same payment |
| A refund | The order and your records update when it's processed |
| Live keys and live notification address | Configured, and the test ones removed from production |
Chapter 11
Reconciling by your own reference
Put your own order or invoice reference on every payment you create. It's the thread that ties the order in your system to the payment, the refund and the settlement line, and it's what lets finance reconcile without asking engineering. API payments settle with your other online payments on your settlement cycle.
| Match | On what |
|---|---|
| Order ↔ payment | Your reference, stored on the payment when it's created |
| Payment ↔ refund | The original payment it belongs to |
| Payment ↔ settlement line | The payment's reference in the settlement report |
How matching works across providers: reconciliation.
Chapter 12
Running it in production
A payment integration needs a little ongoing attention. These are the signals worth watching, and what each one usually means.
| Signal | What it usually means |
|---|---|
| Success rate drops for one method | A provider or bank issue, or a problem in your checkout for that method |
| Pending payments piling up | A provider is slow, or your notification receiver has stopped |
| Notification deliveries failing | Your receiver is down, slow, or rejecting valid signatures |
| Duplicate orders or payments | Missing idempotency keys, or a double-submit in the checkout |
Across several providers, slow ones can be routed around automatically: automatic failover and provider performance.
Chapter 13
When businesses build their own checkout
Building your own checkout pays off when payment is part of the product experience, not a step bolted on at the end.
An app where payment is one step of a larger flow
Pay without leaving the app, in your own screens
A marketplace with its own checkout
One checkout for many sellers, with the split handled after payment
A subscription or membership product
A SaaS or fintech product
For developers
Illustrative pseudo-code: the flow, not Peneu's API. Endpoint, field and event names are confirmed in the API reference.
# server side only
key = idempotency_key_for(checkout_attempt) # same key on a retry
payment = create_payment(amount = 1499_00, reference = "7731", key = key)
save(order = "7731", payment_id = payment.id, status = payment.status)
return payment.next_step_for_customer # UPI app, QR, card or bank page
on notification(n):
if not signature_valid(n) or already_processed(n.event_id): return ok()
status = get_payment(n.payment_id).status # confirm before acting
if status == succeeded: fulfil("7731")
if status == failed: show_retry("7731")
return ok() # acknowledge quicklyFAQ
Collection API questions
What is a payment collection API?
A set of server-to-server requests that let your own website or app create payments, send the customer to the right next step, and find out the result, while you control the checkout screens.
How is it different from a hosted checkout?
With a hosted checkout, the payment page is provided for you. With a collection API, you build the payment experience inside your product and call the API from your server.
Why do payments sit in 'pending'?
Because the customer still has to act (approve in their UPI app, authenticate a card, log in to their bank) or the bank hasn't confirmed yet. Pending is normal; design your checkout to wait for the final status.
What is a webhook?
A notification sent from the payment platform to your server when something changes, such as a payment succeeding or failing. It saves you from asking repeatedly.
Should I trust the webhook or the customer's redirect back to my site?
Neither on its own. The redirect can be skipped or faked, and notifications can be late or duplicated. Treat both as prompts, then fetch the payment's status from your server before fulfilling the order.
What is idempotency?
Making a request safe to repeat. If a create request times out and you send it again with the same idempotency key, you get back the original payment instead of creating a second one.
What should my checkout show when a payment fails?
A clear, customer-level reason (for example, 'your bank declined the payment') and a way to try again or choose another method. Never show raw technical codes.
Do I have to handle card numbers myself?
Not if you don't want to. Card details can be collected by the provider's secure fields or page, which keeps raw card data out of your systems and reduces your security scope.
Is there a sandbox for testing?
Test against a sandbox where one is available for your account, including failures, timeouts and refunds, not just successful payments.
Can I use the API alongside payment links or a hosted page?
Yes. A common setup uses the API inside the product and payment links for one-off or offline requests. Both report into the same payments and settlements.
When does the money reach my bank account?
API payments settle like any other online payments, on your settlement cycle, commonly one or two banking days depending on the method, provider and agreement.
How it works underneath
- Unified APIOne request & status modelView details
- Unified WebhooksOne normalised event streamView details
- One IntegrationConnect once, reach every providerView details
- Reconciliation & ReportingMatch payments & settlements across providersView details
Related products
Sources
- RBI — Harmonisation of turnaround time and customer compensation for failed transactions (RBI/2019-20/67, 20 Sep 2019)Why a failed payment that debited the customer resolves on its own, e.g. a UPI payment to a merchant within T+5.
Last reviewed . Examples, rates and traces marked illustrative are not Peneu figures.
Plan your integration
Tell us what you're building and which methods you need. We'll walk your developers through the flow before a line of code is written.
