Hosted Deposit Page
Redirect users to the Pientegra-hosted deposit page with depositUrl.
In the deposit flow, Pientegra External API does not render a user screen directly.
The partner backend first calls POST /external/deposits; Pientegra returns a
signed depositUrl in the response. The user is redirected to that URL.
This page explains how to use depositUrl on the frontend and what the integration
team is responsible for during the hosted deposit handoff.
Flow
1. The user selects a deposit amount on the partner site.
2. The partner frontend sends a request to its own backend.
3. The partner backend sends POST /external/deposits to Pientegra.
4. Pientegra creates the intent and returns depositUrl.
5. The partner frontend redirects the user to depositUrl.
6. The user sees bank details on the hosted page and confirms that the transfer was made.
7. After review, Pientegra sends an intent.approved or intent.rejected webhook.Page content
The hosted deposit page is rendered according to tenant branding and published page settings. The user sees the following core information:
| Field | Description |
|---|---|
| Amount | Exact amount the user must deposit. |
| Account holder | Owner of the account receiving the transfer. |
| IBAN | Account IBAN for the transfer. |
| Reference | Reference number for support and reconciliation. |
| Countdown | Remaining time based on expiresAt. |
| CTA | User action to confirm "I made the payment." |
Redirect, popup, or iframe
Recommended models:
| Model | When to use it | Note |
|---|---|---|
| Full-page redirect | Mobile web or simple integration | Lowest browser compatibility risk. |
| Popup/new tab | When you do not want the user to fully leave the partner site | Must be opened inside a click handler because of popup blockers. |
| iframe | Only when Pientegra and partner security policies allow it | CSP, frame policy, and browser restrictions must be validated separately. |
For production, the safest default is a full-page redirect or a click-triggered popup.
Popup pattern
depositButton.addEventListener('click', async () => {
const popup = window.open('about:blank', '_blank');
if (!popup) {
showPopupBlockedMessage();
return;
}
try {
const response = await fetch('/api/pientegra/deposits', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount: '100000' }),
});
const body = await response.json();
popup.location = body.depositUrl;
} catch (error) {
popup.close();
throw error;
}
});The partner frontend never knows the Pientegra API key. It only sends requests to the partner backend; the API request to Pientegra is made from your backend.
Expiry behavior
depositUrl is a one-time, signed, time-limited URL. If it expires, the user sees
an expired state and must start a new deposit request.
Important points:
- The user should not pay through an expired URL.
- If funds arrive after expiry, Pientegra may mark the intent as
LATE_ARRIVAL. - Final balance credit must happen only from the
intent.approvedwebhook.
Frontend responsibilities
- Send the amount to the backend in minor units.
- Do not put the API key in the frontend.
- If you use a popup, open the window inside a click handler.
- Do not optimistically increase the balance when the user returns from the deposit page.
- Wait for the webhook outcome before updating the balance.
Backend responsibilities
- Send the
POST /external/depositsrequest with an idempotency key. - Store
intentId,referenceNo,depositUrl, and the request payload. - Use a business idempotency key such as
intent.approved:<intent.id>in the webhook handler. - Use the status endpoint only for support and reconciliation.