Pay-in Webhooks

Understanding Yaspa Pay-in updates

Webhooks are a crucial mechanism for merchants to receive notifications about Pay-in creation and Pay-in status changes. All Pay-in webhooks have a webhook_type that begins with PAYIN_.

Webhook processing and Security

Yaspa Webhooks are sent via HTTPS and are signed. For information on processing and around Webhook security, see the section here - Webhooks.

Pay-in Webhook Events


Webhook

Description

Pay-in Transaction Status

PAYIN_CREATED

Pay-in was created

INITIATED

PAYIN_REDIRECT

The customer selected a bank and was redirected to it

PENDING_USER_AUTHORISATION

PAYIN_EXPIRED

The customer did not consent to the pay-in, and it was not submitted to the customer's bank.

Typically, expiry happens after 30 minutes of inactivity.

EXPIRED

PAYIN_CONSENT_GRANTED

The customer granted consent to continue the pay-in and the pay-in was submitted to the Customer's bank

PENDING_ASPSP_AUTHORISATION

PAYIN_DECISION

A pay-in decision was made by the customer or the customer's bank

ACCEPTED, CANCELLED, REJECTED_BY_ASPSP, or FAILED

PAYIN_ERROR

An error occurred in the Yaspa processing

ERROR

PAYIN_COMPLETE

The funds have been credited to your account (corporate accounts only)

COMPLETE

PAYIN_COMPLETE_CONFIRMED

If we receive a 200 or 201 response to the COMPLETE webhook, and the event type is set, this is sent to the merchant

COMPLETE

Pay-in Webhook payload and Parameters

The pay-in webhooks are HTTPS post requests and a typical example of the request body is as follows:

{
  "type": "PAYIN_COMPLETE",
  "data": {
    "citizenTransactionId": "4b614456-e7b3-bca6-c4f4-ed9abd",
    "merchantId": "67fe73696a9ea33c061f0430",
    "customerIdentifier": "customerid1234",
    "version": "2",
    "journeyType": "HOSTED_PAYMENT",
    "transactionType": "PAYIN",
    "transactionStatus": "COMPLETE",
    "creationDate": 1748022100517,
    "language": "en",
    "paymentGiro": "FPS",
    "customerName": "Citizen Test Account Holder",
    "customerBankCode": "040075",
    "customerAccountNumber": "57583676",
    "merchantTradingName": "The Online Shop",
    "merchantBankCode": "040075",
    "merchantAccountNumber": "65998413",
    "paymentAmount": "1.50",
    "paymentCurrency": "GBP",
    "reference": "ref1234567",
    "paymentProvider": "REVOLUT"
  }
}

There will often be other parameters in the body, such as some of the optional parameters will be carried through the system, as such it's critically important merchant servers do not use strict mode parsing on the above JSON format, otherwise there will be failures to read data from Yaspa.

Parameter list:

ParameterDescription
citizenTransactionIdCitizen transaction ID
merchantIdThe ID of your merchant
merchantTradingNameThe trading name of your merchant
customerIdentifierCustomer ID in your system
customerAccountNumberCustomer account number (only shown for verified pay-in)
customerBankCodeCustomer bank code (only shown for verified pay-in)
customerNameCustomer account holder name (only shown for verified pay-in)
versionVersion of the API
journeyTypeType of journey (e.g. EMAIL)
transactionStatusCurrent status of the transaction (e.g. INITIATED)
searchableTextA string you can use to search for this pay-in
creationDateDate of creation
paymentMethodMethod of payment (e.g. OPEN_BANKING)
paymentGiroPayment rail used (e.g. FPS)
paymentAmountThe amount of the payment
paymentCurrencyCurrency of the payment
payloadMeta-data associated with the payment
payloadEncryptedBoolean indicating if the payload is encrypted
merchantAccountNumberYour merchant account number
merchantBankCodeYour merchant bank code
referenceThe reference given to the pay-in
descriptionThe description shown to the customer
customerEmailAddressThe customer's email address

Pay-in Status

The events above each contain a status; the table below provides more details on what each status means.

TransactionStatusDescriptionTerminal Status
INITIATEDThe journey has begun and the user is about to select the bank he will pay from
PENDING_USER_AUTHORISATIONThe user has selected the bank he wants to pay from and has been redirected to his bank
ACCEPTEDThe pay-in has been authorised by the user and accepted by the financial providerSpecial Case - See below
COMPLETEThe pay-in transaction is completed and funds have been settledYes
CANCELLEDThe user cancelled the pay-inYes
REJECTED_BY_ASPSPThe pay-in has been rejected by the payer or payee's bankYes
EXPIREDThe pay-in has expired without the user authorising itYes
FAILEDThe pay-in failed to be authorised by the bankYes
ERRORAn error occurred during the pay-in journey. e.g INVALID_CONFIRMATION_CODEYes

When a terminal status is reached under normal operation, there will be no further events for the pay-in. Merchants should configure the admin dashboard to receive all terminal status webhooks. Non-terminal status webhooks can mostly be ignored, unless the merchant has special requirements or wants a more complete log of the customer's progress.

However, there has been one or two scenarios where banks have had issues, and returned status FAILED, but pay-in has settled. In these cases Yaspa will send a PAYIN_COMPLETE webhook with the Status COMPLETE to let the merchant know the funds have arrived. As such Yaspa suggests all COMPLETE Statuses are considered carefully.

Statuses for Successful Payments

The two most important Statuses for successful pay-in are as follows:

ACCEPTED – The customer bank has committed to sending the merchant bank the pay-in. 99.9% of payments which reach ACCEPTED will reach COMPLETE. COMPLETE – The pay-in has settled into the merchant bank account.

The 0.1% of pay-ins that were sent by the customer banks but not received by the merchant bank happen in the very rare case there is a problem on the payment rails, or when the merchant bank flags the pay-in for PEPs or sanction checks and the merchant fails to provide KYC data for the customer.

Given the high level of accuracy of the ACCEPTED status, many merchants making payments in EUR decide to release goods and services on the ACCEPTED status. They do this because whilst most banks send payments via SEPA Instant which takes seconds to settle, there are a minority of banks that send EUR payments via SEPA Credit Transfer (SCT) which can take 2 business days to arrive.

Yaspa is happy to advise how payments will work in the merchant's particular banking region, but ultimately, the decision on when merchants will release goods and services is up to the merchant.