Future-dated Payments

As discussed in the previous topic on single immediate payments, future-dated transfer token requests, regardless of the Token.io.io SDK chosen, are created with the selected-language variant of the transferTokenRequestBuilder() method. Once the token request is created, you store it, awaiting a corresponding request-id, which is returned by Token.io in a response payload. In addition to the request-id, the response payload reflects all the information you included in your original request. Now equipped with the request-id, you can set your transfer destination(s), if you omitted it in the originating token request, and redeem the token, thereby transferring the specified payment amount from the payer's bank account to the payee's bank account on the future date specified.

Tip: Remember, in the examples that follow, classes, methods and parameters are initially presented in their default Java syntax. Select the corresponding tab — Java, JavaScript or C# in the navigation bar of the first code example in the sequence — to display the correct syntax and field names for the SDK language chosen.

For future-dated payments, executionDate must be set in transferTokenRequestBuilder(). Remember, it must be a date in the future or an error will be thrown.

/**

 * Creates and stores a transfer token request.

 *

 * @param payee Payee Token.io member (member requesting transfer token creation)

 * @return a token request id

 */

public static String storeTransferTokenRequest(Member payee) {

    // build the transfer token request for single immediate payment

 

    // first, set the transfer destination

    TransferDestination sepaDestination = TransferDestination.newBuilder()

        .setSepa(TransferDestination.Sepa.newBuilder()

            .setBic("XuiWC2489")

            .setIban("DE89 3704 0044 0532 0130 00")

            .build())

        .setCustomerData(TransferInstructionsProtos.CustomerData.newBuilder()

            .addLegalNames("merchant-sample-java")

            .build())

        .build();

 

    // then build the request

    TokenRequest request = TokenRequest.transferTokenRequestBuilder(100.00, "EUR")

        .setExecutionDate("2021-12-31")

        .setToMemberId(payee.memberId()) // member ID of payee

        .setToAlias(payee.firstAliasBlocking()) // member alias of payee

        .setDescription("Book purchase") // description of payment/transfer

        .addDestination(sepaDestination)

        .setRedirectUrl("https://tpp-sample.com/callback") // TPP callback URL

        .setFromAlias(Alias.newBuilder()

            .setValue("payer-alias@token.io") // payer's alias

            .setType(Alias.Type.EMAIL)

            .build())

        .setCsrfToken(csrfToken) // validates the session ID

        // use keys in bank authorization metadata from getBanks() response

        .putAllAuthorizationMetadata(new HashMap<>())

        .build();

 

    // now store the token request

    return payee.storeTokenRequestBlocking(request);

}

The key fields comprising a token request for a future-dated payment are defined in the following table.

Fields in a Transfer Token Request for Future-dated Payments
Field Description Required/ Optional
actingAs Party or entity for which the to member is acting as a proxy. See Creating a Token.io on Behalf of another Party for details on setting the properties for this field. Optional
amount Payment value calculated in currency.

Precision: Recommended precision is rounding to 4 decimal places (), although the TPP can set its own desired precision. However, be aware that certain banks may handle rounding differently — some with greater precision (i.e., more decimal places), others with reduced rounding precision (fewer decimal places). The Token.io Platform strictly serves as the pipeline between the TPP and the bank, imposing no precision restrictions.

Required
authorizationMetadata Needed to capture additional information from the user for initial authorization by the bank, thereby allowing the user to proceed with providing consent for the initiation request. Maps the key-value pairs from the getBanks() response, where key is the name of the field and value is the value of the field. Required
bankId When specified, indicates you wish to bypass the Token.io bank selection UI and use your own bank selection UI for the request. See Using the getbanks Method. Optional
callBackState TPP-specified string that persists state between request and callback. Optional, but recommended
currency ISO 4217 alpha-3 currency code. Required
description Description of the payment with the following qualifiers:
  • description in a subsequent call must match description in originating request
  • description omitted in originating request must also be omitted in subsequent calls
  • description omitted in subsequent call will be replaced with refId

This description field maps to description in the bank's consentRequest presented to the user.

Warning: If description in a subsequent token request for lookups/changes/updates (retrieve, redeem, or cancel) doesn't match the description in the originating token request, an exception will be thrown.

Optional
executionDate Sets the date for executing the future payment in ISO 8601 format. Required
from member_id or alias of the user; if included, indicates you wish to bypass the Token.io user email entry UI. See Specifying User Email Address. Optional
member The customer/user; payer of the token. Required
receiptRequested Boolean; requests a receipt be sent to the from member's default email address. Optional
reference Augmenting refId and description, this is TPP-defined additional information pertinent to TPP's payments policies; for instance, could contain a full or partial credit card number when payment is being initiated for a credit card payment. Securely hashed to safeguard its transmission throughout the communication flow, this field should be considered by TPPs wishing to augment their transaction reference data for tracking and audit control. Optional
redirectUrl Specifies the callback URL where your server will initiate token redemption. Required
refId Reference identifier for the token; not to be confused with requestId. RefId is typically used by the TPP to reconcile transactions against payments received. RefId maps to tppRefId in the bank's consentRequest. It is needed to match/verify the originating token request with the bank's consent request.

Warning: A description mismatch between the originating token request and subsequent token lookups/changes/updates (retrieve, redeem, or cancel) will throw an exception.

Required
sourceAccountId Account number from which the amount is being debited; set using the AccountIdentifier object, which allows four types of account identifiers:
  • Token, for linked accounts
  • Iban
  • Bban
  • GbDomestic – 8-digit bank account number in the UK

Although setting source with the BankAccount object has been deprecated, it is still supported

Optional
to member_id and alias of the transfer recipient Required
token_expiration Sets the expiration date and time for the token request (default is 20 minutes); override of default value is not supported by all banks. Optional
traceID TPP-provided unique value captured by Token.io and sent across to the bank to be stored with the request throughout its lifecycle as an audit-trail aid. Optional
transferDestinations Payment beneficiary bank account(s); where payment will be sent. Typically an for , or and Account Number(s) for . See Beneficiary Account Details for supported instruments.

Required by some banks, optional for others, the type of destination account (business or personal) is specified under transferDestinations in customerData.type as UNKNOWN, BUSINESS or PERSONAL. When not specified, the default destination account type is BUSINESS.

A creditor name (customerData.legalNames) for the destination account is a required subfield parameter: transferInstructions.transferDestinations.customerData.legalNames

Required
userRefId Identifier that can be used to track a user member claimed by the TPP. Optional

Caution: A is disallowed in the token request payload within the refId and description fields. In accordance with the security standard, is used for pattern matching of numeric strings that intentionally or inadvertently reveal or resemble a PAN in the refId or description of a token request. Potential PAN patterns found will now throw an exception.

Remember, whatever you specify as the transferDestination in the request will be reflected in the response. This means accuracy is extremely important here.

Payee Information

Submission and return of payee information is not supported by all banks. When supported, and based on the standard adopted by the bank, creditor account (payee) information (legal name and/or address) is included in customerData within providerTransactionDetails for single transactions. When included in the request, payee/creditor account information is available in the response, regardless of the API standard adopted by the bank; typically, however, the following guidelines apply:

  • STET requires creditor account information.

  • CMA9, NextGenPSD2, and PolishAPI have the creditor name and account identifiers, as well as the creditor agent BIC. However, these are optional fields, so the presence of creditor account information is bank-dependent.

  • CMA9 needs the creditor agent address, whilst PolishAPI requires the creditor's address.

If you are initiating a payment to Barclays Bank UK or HSBC, the creditor name (creditorAcount.name) can be no more than 18 characters. If this limit is exceeded, the bank will reject the payment.

Otherwise, when providing creditor name and address for CMA9 international payments, bear in mind that certain banks, such as HSBC, require creditor information to process international payments, despite its designation as "optional" in the OBIE specification. To be safe with respect to CMA9 international payments, provide this information in the customerData fields of the transferDestination object. The OBIE information maps to its Token.io counterpart as follows:

Token.io OBIE
flats SubDepartment
house_name Department
house_number BuildingNumber
street StreetName
post_code PostCode
city TownName
district CountrySubDivision
country Country

You can store the created request without a transfer destination and, instead, specify a transferDestinationsCallback URL for Token.io to call upon customer authentication and authorization. Or, you can specify the destination when you redeem the token. Additional details can be found in Setting Transfer Destinations.