Implementing your own payment validation webview
In this guide, once the payment has been created on the API, we will validate it without using Powens' Webview.
Last updated
In this guide, once the payment has been created on the API, we will validate it without using Powens' Webview.
Last updated
This guide assumes you are authorized to implement your own webview. If you don't know whether you are or not, ask your commercial contact about it.
This guide assumes that you have the following elements:
A Powens domain with Pay enabled.
A payment, regardless of its type, with the "created"
status.
A payment validation webview must be isolated, with a defined role and behaviour whatever its design integration is. This role is described here, through specific steps and conditions the webview must traverse to validate the current operation on a payment.
At startup, the webview must get the current state of the payment:
If the payment's state is created
, then the webview can do the steps to validate the payment.
If the payment's state is validating
and the current action is not confirm
, then the webview can continue to handle interactive steps.
Otherwise, the payment is unsuitable for validation by the webview, and the end user should be redirected to the final redirect URL with a suitable state.
Note that this request is also required to get other information regarding the payment, e.g. to determine the constraints applied to obtain eligible connectors.
The Pay API does not support changing webviews during a single payment validation flow. If the payment is already in the validating
state, this guide assumes that the initiation payment validation was done by the same webview, and either the end user has reloaded the page (e.g. resumed the flow due to a client-side crash), or came back from a redirect flow with the bank.
This section is required if the payment is currently in the created
state.
Validating the payment is about placing it in a state where we have to answer interactive steps. In order to do this, we must prepare a few properties before validating the payment.
If the connector isn't set yet on the payment, i.e. if connector_uuid
is set to null
on the current status of the payment, you need to pick a connector for the payment. In order to find available connectors for making payments, you need to make the following request:
Connectors supporting the Pay product, identified by having "pay"
in its products
list, will define a payment_settings
object, which present Pay constraints and features for this specific connectors. You need to filter them on the client side, depending on the payment:
The connector must have "pay"
in its products
list.
The payment's number of instructions must be less or equal to maximum_number_of_instructions
from the connector's payment_settings
.
For all instructions of the payment:
The instruction's execution_date_type
value must be present in the execution_date_types
within the connector's payment_settings
.
The instruction's scheme_name from beneficiary value must be present in the connector's beneficiary_types
attribute in payment_settings
.
If the instruction has an execution_date_type
set to periodic
, the frequency
is present in execution_frequencies
from the connector's payment_settings
.
Beyond these standard filters, you can also apply yours depending on your configuration:
If you want to avoid having to ask the end user for their IBAN, you can avoid connectors with the providing_payer_account
set to mandatory
.
If you want to avoid payments ending in the accepted
state, you can ensure that every instruction has an execution date type that isn't included in the connector's partial_status_tracking
list.
If you want to get the top connectors for Pay in terms of number of payments in the last month, in case you want to display them on top, you can request such connectors with the following request:
Note that this request may return less than the number of connectors specified in the top
parameter, for example it may return 7 connectors if all payments created in the last month have been affected only 7 connectors out of all possible connectors.
The connector you've chosen provides a given set of validation mechanisms, in the available_validate_mechanisms
attribute of the payment_settings
at connector level. It is recommended to check which validation mechanisms you want to use at this stage.
If you're not a white label, you must either restrict the connector list to connectors bearing the webauth
(or any mechanism starting with webauth_
) validation mechanism, or set the connector to the payment and redirect to Powens' webview, as you are not allowed to handle non-webauth
validation mechanisms in your webview.
Note that the procedure stops here if you redirect to Powens' webview at this stage. You are not to validate terms for the payment; Powens' webview will take care of this.
If you are a white label, this section is optional.
First, the terms of service must be accepted by the end user. In order to do so, you must do the following call:
If the to_sign
attribute is both present and set to true
, then the terms of service are to be accepted by the end user.
If the terms of service have not been accepted yet, you can get the content to display to the end user by making the following request:
In order to signify the acceptance of the terms of service for the payment by the end user, you can make the following request:
In order to check if fields are to be sent to the connector, you need to get the connector fields by making the following request:
The website field should be requested from the end user if the validation mechanism chosen beforehand is present in the auth_mechanisms
array in the field definition.
Regardless of whether you are a white label or not, you MUST use front encryption on all fields before transmitting them. See End-to-end encryption for more information.
If the connector's UUID was already provided in the payment by the webview's client, you need to request the connector's information here by calling GET /connectors/{connectorUUID}
.
If providing_payer_account
in the connector's payment_settings
is set as mandatory
, then the payer's identification must be requested from them.
From the previous sections, you now have obtained the following information for validating the payment from the end user:
The connector UUID (if it wasn't already set).
The validate mechanism.
The field values, passed through end-to-end encryption (if at least one is set).
The payer account identification (if it is required).
The callback URL for redirect
actions (as webview_url
).
You must prepare a webview_url
, in order to redirect the end user back to your webview to continue the validation process for the payment after redirect
actions. This URL can contain query parameters which will be included in the callback.
In case of multiple redirect steps, the end user will always be redirected to the same webview URL as provided in the validation request. Please ensure that you don't have nonces in said URL.
You can now validate the payment, in order to pass it from the created
state to validating
:
The payment is now initiated, and interactive steps need to be taken for the payment to be fully validated.
Either after successfully validating a payment in the created
state or resuming validation on a payment in the validating
state, interactive steps need to be taken towards continuing the operation.
The current validation step is represented by the action
property of the payment.
This means that a redirect flow is to be accomplished by the end user. In this case, you must redirect the end user to the URL present in the validate_uri
attribute of the payment.
The URL MUST NOT be used in an iframe, only in full redirect, as it might be app-to-app compatible on mobile devices.
At the end of the redirect flow, the end user will be redirected back to the webview through the URL you've defined in the webview_url
attribute of the validation request.
This means that a validation has been requested through another channel, such as a notification in a mobile application, or a link sent by e-mail or SMS. In this case, you must inform the end user that the validation is taking place, then request a check on the decoupled validation status with a 10 second delay, using the following request:
The 10 second timer should start after the response is received. For efficiency, some connectors may internalize part of the polling, which means the request defined above could take more than 10 seconds.
This means that an additional information is required from the end user, such as one-time passwords or the identifier of the account to select for the payment. In this case, you must get the list of fields to ask the end user.
For example, the payment will resemble this:
And, in order to submit the values picked by the end user back to the API, a request such as this one must be made:
This means that presenting a summary of the payment to the end user and letting them choose whether or not they want to pursue the validation flow is recommended at this point. This is mostly used when no redirect flow is available to do this, but a webview may emulate end user consent on such actions.
In order to communicate that the end user consents to pursuing the validation flow, the following request should be made:
If however, the end user chooses not to pursue the validation flow, the following request should be made:
This means that payment validation confirmation is expected from the client. This must be considered as a "pending"
payment state by the webview, which should redirect the end user to the client redirect URL and state.
Different use cases are provided with the test connector to trigger specific validation mechanisms during the validation process. This will allow you to verify that you have correctly implemented the different interactive steps.
The field openapiwebsite
can be ignored when initiating payments.
In order to choose a use case for your payment on the test connector, you need to provide it as part of the expected fields.
Here's an example of how to initiate a payment with the redirect
use case.
From there, the payment will follow a specific sequence of required actions from your part in order to be validated.
In the following sections we will see the specifities of each available use case.
Upon validation, the payment enters the validating
state with a redirect
action. The redirection URI is provided in the validate_uri
field.
You need to redirect the end user to the provided address, which will allow the payment to be validated and change its state to done
. After which your end user would be redirected to webview_url
.
This use case will trigger a decoupled validation and ends with a payment in the state done
.
Upon validation, the payment enters the validating
state with a decoupled
action. The error_description
field contains an example description you could get from a real connector. You don't really have to validate the operation anywhere here, this is just an example for you to display in your validation webview.
From here you can poll the payment until its state changes to done
. The validation takes approximately 10 seconds to occur.
This use case will trigger a decoupled validation and simulate a cancellation by the PSU in the decoupled channel.
Upon validation, the payment enters the validating
state with a decoupled
action.
After approximately 10 seconds, the payment state will change to rejected
, with the error_code
CancelledByUser
.
This use case will trigger a decoupled validation and simulate an expiration of the authorization process.
Upon validation, the payment enters the validating
state with a decoupled
action.
After approximately 20 seconds, the payment state will change to rejected
, with the error_code
authenticationFailed
.
This use case will require the end user to input a one time password.
Upon validation, the payment enters the validating
state with an additionalInformationNeeded
action. The one time password is requested in the fields
key of the response.
From here there are two possibilities:
Provide the code 1234
to validate the payment. The payment state changes to done
.
Or you can provide anything else to reject the payment with the authenticationFailed
error_code
.
This use case simulates a payment validation chaining a one time password prompt followed by a decoupled validation. This is useful to check that your webview implementation supports more than one validation mechanism at a time.
This chains the use case "One time password (SMS)" and "Decoupled with successful validation".
This use case triggers a payment validation where the PSU needs to select the payment account to debit for this operation. This is done through an additional field of type list
.
Upon validation, the payment enters the validating
state with additionalInformationNeeded
action. The dynamic field exposes a list of available payment accounts.
Depending on the chosen account, the operation result will vary:
If the main account is chosen, the payment will be successfully authorised and the state will change to done.
If the snd
account is chosen, the payment will be rejected with the invalidEmitter
error_code
.
This use case can be useful if you have disabled automatic payment confirmation on your domain, but still wants to test a case where such a confirmation is not available.
The validation mechanism is the same as the redirect use case, with the exception that the payment state will change to done without a confirm
action beforehand.
The legacy use case allows you to specify the states that the payment will go through during its lifecycle. This can be used to test the webhooks, an early rejection or a pending state. This use case is fully covered in the following guide :Validating your implementation with the test connector.
It's useful whether you use your own webview or not. This use case is chosen by default if do not provide a value for the use_case_pay
field when validating a payment on this connector.