Instant Card Top-Ups
Introduction
This page contains step-by-step instructions on how to implement the Instant Card Top-Ups feature in your solution.
Product overview
The Instant Card Top-Ups via Acquirer feature allows your customers to instantly add funds to their account using a card (debit or credit) or a digital wallet (e.g., Google Pay or Apple Pay). In short, customers enter the desired amount to top up their account in your frontend, and then Solaris credits these funds to the customer's account.
Solaris offers this feature in cooperation with Stripe (referred to throughout this guide as the "Acquirer"). The Acquirer collects card details from the customer and processes the payment, while Solaris credits the Top-Up funds to the customer's account immediately after the payment is processed. To use this feature, you must integrate both the Solaris Top-Up APIs and the Acquirer's SDK.
Top-Up product flow
The sequence diagram below shows the process of collecting payment information from the customer in the frontend and how Solaris and the Acquirer process it on their respective backends.
To view a larger version, right-click the image and click "Open in a new tab."
User journey
The product flow consists of the following steps:
-
Provide your customer a screen to request a Top-Up and specify the Top-Up amount.
- Perform soft validation on the client side to ensure that the Top-Up amount fits within the minimum and maximum allowed amounts.
- Call the POST Create a Top-Up method to start the payment process.
- If all validation checks are successful (e.g., Top-Up limits), then the Solaris API will call the Acquirer's API to create a payment object on their backend. Otherwise, the API will return an error.
-
Present your customer with a screen to collect their card details.
- If using Stripe in a mobile app, then use Stripe's predefined UI element.
- The customer enters their card details, and then the Acquirer will initiate a 3DS challenge, which the customer must authorize. This step occurs in your frontend using the Acquirer's SDK.
- Once the Top-Up has been authorized and successfully processed, Solaris will trigger the clearing of the funds from its buffer account with the Acquirer.
- The funds will be credited instantly to the customer's account for the amount specified in step 1. Later, the Acquirer will settle the funds in the buffer account in a pre-defined settlement cycle, e.g., T+2.
note
You must cancel a Top-Up if a customer has dropped from the Top-Up session in
your solution. If a created Top-Up's status is left as ACCEPTED
and the
customer never completes it, then it will count toward the monthly Top-Up limit
set by Solaris until it is canceled.
Prerequisites
You can only implement this feature after you have onboarded your customers with bank accounts and cards. See the Get started guide for instructions on how to implement the customer onboarding process for Digital Banking & Cards.
1. Integrate Acquirer SDK
Before implementing Solaris' Top-Ups APIs, you must integrate the Acquirer's SDK in your solution to collect your customers' payment details.
Stripe PaymentIntents and PaymentSheets
Stripe's PaymentIntent
object represents your intention to collect a payment
from a customer. It tracks the state of a payment using a multi-step state
machine. If the payment succeeds, then the final state of the PaymentIntent
will be succeeded
.
Stripe's Android and iOS SDKs include a PaymentSheet
UI component. The
PaymentSheet
provides all of the necessary UI elements to collect payment data
from your customer. The mobile SDKs tokenize sensitive payment details within a
PaymentSheet
, which allows you to accept different payment methods within a
single integration.
See the documentation links below for more information:
Passing the customer's billing address to Stripe
You are required to use the customer's address information from their
person resource as the billing address of the payment that will be
processed by Stripe. Solaris recommends filling this information in on your
frontend on behalf of the customer. Use the following properties from the
address
object on the customer's person resource:
line1
postal_code
city
country
Handling payment errors
Your solution may encounter errors when making requests to the Stripe API. Stripe's documentation provides general information on error handling as well as a list of all error codes that can occur.
Note that Stripe uses special codes for card declines.
Apple Pay integration
To offer Apple Pay as a payment method for Card Top Ups, you must follow the steps below:
- Register for an Apple Merchant ID. See the Stripe documentation for instructions.
- Configure the Apple Pay certificates for iOS and/or web. For this step, you must coordinate with your Account Manager or assigned TSE, as this is managed between Solaris' Stripe account configurations and your implementation.
Stripe SDK documentation
note
You may ignore all server-side implementation details in the following documentation resources, as Solaris provides all necessary credentials and endpoints.
Click the links below to learn how to integrate Stripe's web, iOS, and Android SDKs, depending on which platform(s) your solution runs on:
Stripe.js (web integration)
- Stripe.js - Integration Guide
- Stripe.js Reference
- Stripe.js Reference - PaymentIntents
- StackOverflow
- Stripe Developers Discord
Android
- Stripe Android SDK
- Stripe Android SDK - Reference
- Stripe Android SDK - Integration Guide
- Example app: PaymentSheet
- StackOverflow
- Stripe Developers Discord
iOS
- Stripe iOS SDK
- Stripe iOS SDK - Reference
- Stripe iOS SDK - Integration Guide
- Example apps
- StackOverflow
- Stripe Developers Discord
(iOS only) A note about singletons
The Stripe iOS SDK makes use of the singleton, a common pattern in iOS development across Objective-C and Swift. The singleton pattern guarantees that only one instance of a class is instantiated and that your solution uses that instance to interact with the class. Singletons also provide global access to that instance, which eliminates the need to pass it around to different components.
Stripe's iOS SDK indicates singletons using the property names sharedInstance
,
shared()
, and default()
. Examples:
STPPaymentConfiguration.shared()
(API keys and other configs)STPAPIClient.shared()
(make Stripe API calls)STPTheme.default()
(theming configuration for UI components)STPPaymentHandler.shared()
(for authenticating SCA payments)
If you create an API client class that interfaces with your own local or hosted web server, common practice indicates that you should create a singleton instance out of it, too. To do so, simply create a static property on the class as follows:
static let sharedInstance = API_Client()
You can read more about singletons here: What Is a Singleton and How To Create One In Swift
One common mistake that iOS developers make is to set their API keys on a new
instance of STPPaymentConfiguration
instead of on the singleton. Then, when
they use the SDK, it returns the error of "no API keys," and the problem can be
difficult to debug.
2. Subscribe to webhooks
Subscribe to the following webhook events to receive notifications on key events related to Top-Ups:
- ACQUIRER_TOPUP_EXECUTED:
Triggered when Solaris successfully processes a Top-Up via an Acquirer. The
funds from the Top-Up are cleared to the customer's account, and the
status
of the Top Up changes toEXECUTED
. - ACQUIRER_TOPUP_DECLINED:
Triggered when a Top-Up transaction is declined by Solaris. The
status
of the Top-Up will change toDECLINED
and any charge to the cardholder will be refunded. - ACQUIRER_TOPUP_PAYMENT_FAILED:
Triggered when the payment processing for a Top-Up fails (e.g., if the card
does not have sufficient funds to complete the transaction). The status of the
Top-Up will remain
ACCEPTED
. You may prompt the customer to retry the Top-Up with the same payment method or with a different one.
3. Create and service Top-Ups
After completing the steps above, you are now ready to call the Solaris Top-Ups API endpoints.
Rules and validations
Please note that each created Top-Up must pass the following checks:
- Maximum Top-Up amount: The maximum amount allowed for an individual Top-Up. The default maximum is 2000,00 EUR as per compliance requirements. Please double-check with your Partner Manager about the limit in place for your solution.
- Monthly cumulative Top-Up amount: The maximum Top-Up amount allowed per customer per month. The Solaris Compliance team will define this limit.
POST Create a Top-Up
This method creates a Top-Up object, which begins the payment process with Solaris and its acquiring partner (e.g., Stripe).
The response to a successful request includes a client_secret
ID that
corresponds to the client_secret
of the Payment object ("payment intent") of
the Acquirer. You must provide this to the SDK to confirm the card payment with
the Acquirer.
If the customer is using a previously saved card for the Top-Up, then you must
provide the card's payment_method_id
in the request body. See the payment
methods section below for instructions on how to
get a card's payment_method_id
.
Request URL:
POST /v1/persons/{person_id}/accounts/{account_id}/topups
Request example:
{
"amount": {
"value": 10000,
"currency": "EUR"
},
"payment_method_id": null
}
Response example:
{
"id": "b76cdcc321d345618084feedc47bbb1d",
"amount": {
"value": 10000,
"currency": "EUR"
},
"acquirer_error_code": null,
"acquirer_decline_code": null,
"cancellation_reason": "abandoned",
"decline_reason": null,
"client_secret": "pi_1DrPlP2eZvKYlo2CSBQ7uqFH_secret_o1A7UsYFLWeGISUD1QYNkT8IU",
"status": "EXECUTED",
"instruction_id": "3eba1ee2d8bc4d5883d350031a5fe9d8"
}
Click here to view the full API reference.
GET Index Top-Ups for a customer
This method returns a list of all Top-Ups for a given customer.
Request URL:
GET /v1/persons/{person_id}/accounts/{account_id}/topups
Response example:
[
{
"id": "b76cdcc321d345618084feedc47bbb1d",
"amount": {
"value": 10000,
"currency": "EUR"
},
"acquirer_error_code": null,
"acquirer_decline_code": null,
"cancellation_reason": "abandoned",
"decline_reason": null,
"client_secret": "pi_1DrPlP2eZvKYlo2CSBQ7uqFH_secret_o1A7UsYFLWeGISUD1QYNkT8IU",
"status": "EXECUTED",
"instruction_id": "3eba1ee2d8bc4d5883d350031a5fe9d8"
}
]
Click here to view the full API reference.
GET Retrieve a Top-Up
This method returns the details of a specific Top-Up.
Request URL:
GET /v1/persons/{person_id}/accounts/{account_id}/topups/{topup_id}
Response example:
{
"id": "b76cdcc321d345618084feedc47bbb1d",
"amount": {
"value": 10000,
"currency": "EUR"
},
"acquirer_error_code": null,
"acquirer_decline_code": null,
"cancellation_reason": "abandoned",
"decline_reason": null,
"client_secret": "pi_1DrPlP2eZvKYlo2CSBQ7uqFH_secret_o1A7UsYFLWeGISUD1QYNkT8IU",
"status": "EXECUTED",
"instruction_id": "3eba1ee2d8bc4d5883d350031a5fe9d8"
}
Click here to view the full API reference.
POST Cancel a Top-Up
This method cancels a requested Top-Up. You must provide the cancellation reason
in the request body (in the cancellation_reason
property).
note
You must cancel a Top-Up if a customer has dropped from the Top-Up session in
your solution. If a created Top-Up's status is left as ACCEPTED
and the
customer never completes it, then it will count toward the monthly Top-Up limit
set by Solaris until it is canceled.
Request URL:
POST /v1/persons/{person_id}/accounts/{account_id}/topups/{topup_id}/cancel
Request example:
{
"cancellation_reason": "abandoned"
}
Response example:
{
"id": "b76cdcc321d345618084feedc47bbb1d",
"amount": {
"value": 10000,
"currency": "EUR"
},
"acquirer_error_code": null,
"acquirer_decline_code": null,
"cancellation_reason": "abandoned",
"decline_reason": null,
"client_secret": "pi_1DrPlP2eZvKYlo2CSBQ7uqFH_secret_o1A7UsYFLWeGISUD1QYNkT8IU",
"status": "CANCELLED",
"instruction_id": "3eba1ee2d8bc4d5883d350031a5fe9d8"
}
Click here to view the full API reference.
4. Payment method servicing
Implement the following API calls in your solution to interact with a customer's stored payment methods:
GET Index payment methods for a customer
This method returns all payment methods that a customer stored in your frontend. Solaris retrieves information about stored payment methods from the Acquirer SDK.
Request URL:
GET /v1/persons/{person_id}/topups/payment_methods
Response example:
[
{
"person_id": "18de883f507d49b8a074519c73cecper",
"payment_method_id": "53165f2b3a8846bd9fd344342a6093d6",
"card_last4": "7654",
"card_brand": "mastercard"
}
]
Click here to view the full API reference.
DELETE Remove a customer's payment method
This method removes a customer's stored payment method.
Request URL:
DELETE /v1/persons/{person_id}/topups/payment_methods/{payment_method_id}
Response example:
{
"payment_method_id": "53165f2b3a8846bd9fd344342a6093d6"
}
Click here to view the full API reference.
5. Testing
Appendix I: Top-Up status values
The table below contains all possible status values for a Top-Up and descriptions of what each one means:
Status value | Description |
---|---|
ACCEPTED |
The customer has requested the Top-Up and all checks have passed. Solaris will create a payment object with the Acquirer, pending authentication and authorization. If the Top-Up fails to execute (e.g., due to insufficient funds on the customer's card or failure to complete 3DS authentication), the Top-Up will retain this status value until the Top-Up is successfully executed (e.g., with another payment method). |
CONFIRMED |
The customer has successfully authenticated the Top-Up (e.g., using 3DS) and the Acquirer has successfully processed the payment, but the funds have not yet been cleared to the customer's account. |
EXECUTED |
The Top-Up funds have been cleared to the customer's account. |
DECLINED |
The Top-Up was declined by Solaris due to an internal validation (e.g., the customer's account was blocked at the time of payment processing by the Acquirer). In such cases, the transaction will be refunded to the cardholder automatically. |
CANCELLED |
The Top-Up was cancelled using POST Cancel a Top-Up. This usually occurs when a user drops out from the Top-Up session or if the customer does not confirm the Top-Up in a timely manner. |