Skip to main content
Use this recipe to collect funds instantly. Submit a Request To Pay payload with the debtor identifier, then wait for the customer to approve inside their banking app.

Prerequisites

  • {{aggregator_id}} and {{secret_key}}
  • aggregator_merchant_identifier for the merchant collecting funds
  • Debtor IBAN or Raast ID

Flow summary

1

Load merchant identifiers

Retrieve the aggregator_merchant_identifier from the merchant creation response.
2

Validate the debtor account

Use the account validation utilities to confirm the debtor details.
3

Create the RTP Now payment

Call POST /v1/aggregators/{{aggregator_id}}/payments with type: RTP_NOW.
4

Track the outcome

Use webhooks (and optional polling) to surface the final payment status.
Set {{base_url}} to https://dev.api.getsafepay.com/raastwire in Sandbox or https://api.getsafepay.com/raastwire in Production.

RTP now

request_id
string
required
UUID that enforces idempotency. Reuse only when retrying the exact same payload.
amount
integer
required
Amount in paisa (PKR minor units). 94000 represents PKR 940.00.
aggregator_merchant_identifier
string
required
Token returned in data.token when you created the merchant.
order_id
string
required
Merchant reference echoed in responses and webhooks.
type
string
required
Must be RTP_NOW for immediate Request To Pay flows.
expiry_in_minutes
integer
Required for RTP Now payments. Valid range 1-180 minutes.
debitor_iban
string
Provide when charging a known IBAN. At least one of debitor_iban, debitor_raast_id, or debitor_vault_token must be supplied.
debitor_raast_id
string
Supply when requesting payment via a Raast alias (for example, phone number). One of the debtor identifiers is required.
debitor_vault_token
string
Reference to a stored payment method for repeat customers. One of the debtor identifiers is required.

Monitor status

Use webhooks as the primary source of truth. Polling is helpful for dashboards or fallback workflows.
cURL
curl --request GET "{{base_url}}/v1/aggregators/{{aggregator_id}}/payments/{{payment_token}}" \
  --header "X-SFPY-AGGREGATOR-SECRET-KEY: {{secret_key}}"

Webhook events to expect

  • payment.created
  • payment.pending_authorization
  • payment.authorized
  • payment.completed
  • payment.settled
  • payment.rejected
  • payment.failed
  • payment.voided
  • payment.reversed
  • payment.refunded (if you issue refunds)
  • payment.refund_partial (if you issue partial refunds)
Combine polling with webhooks so your UI updates as soon as the customer accepts or rejects the request.

Troubleshooting

  • Invalid debtor details - Use the validation utilities before sending the RTP.
  • Expired request - Regenerate the RTP with a fresh request_id and expiry_in_minutes.
  • Duplicate payload - Reusing a request_id with different parameters returns an idempotency error; retry with the same body.

See also