Manage Funding Sources
Provides the essentials for a user to link their real payment methods with a virtual card.
Funding sources supply the means for a user to link a real funding source with a virtual card. A user can supply their credit or debit card, or their checking or savings bank account as a method to fund a transaction performed on the virtual card.
A funding source is created by invoking a series of steps from the retrieval of funding source configuration to setup and completion of the creation process.
Any existing virtual cards funded by a cancelled funding source will become unfunded. These can be funded by creating a new funding source and setting the
updateCardFundingSource
parameter in the completeFundingSource
method call to true.Before creating a funding source, the identity of your user must first be verified via Secure Id Verification.
Currently only credit and debit cards are supported as funding sources
To begin the process of creating a funding source, call the
setupFundingSource
method. The funding source providers that your client application supports will inform which provider names you provide to the setupFundingSource
method call. Funding source providers supported by the Virtual Cards service include stripe
and checkout
.TypeScript
Swift
Kotlin
try {
const provisionalFundingSource = await virtualCardsClient.setupFundingSource({
currency: 'USD',
type: FundingSourceType.CreditCard,
// include only the provider(s) you will support
supportedProviders: ['stripe', 'checkout'],
})
} catch (error) {
// Handle/notify user of errors
}
The call to
setupFundingSource
will return a ProvisionalFundingSource
containing provisioning data required to continue the funding source creation process. To continue, you must use either the Stripe API or the checkout.com API to progress the funding source setup; the chosen provider must match that returned in the provisionalFundingSource.provisioningData
property.Retrieve the provider API key as well as other information pertaining to the funding source provider using the
getFundingSourceClientConfiguration
method:try {
const configuration =
await virtualCardsClient.getFundingSourceClientConfiguration()
// [configuration] contains the list of funding source client configuration.
} catch (error) {
// Handle/notify user of errors
}
Stripe Funding Source Preparation
For Stripe React integration, see the documentation at:
For Stripe JavaScript integration, see the documentation at:
To setup a payment intent in Stripe, call
StripeClient.confirmSetupIntent(confirmSetupIntentParams: ConfirmSetupIntentParams)
and ensure that the ConfirmSetupIntentParams
input parameter is populated with card details and billing details that you wish to add as a funding source.Card and Billing Details are required.
Once a Setup Intent has been setup, call
completeFundingSource
to finish provisioning the FundingSource
.checkout.com Funding Source Preparation
For checkout.com JavaScript, see the documentation at:
A React wrapper for their Frames library is available at:
To retrieve the tokenized card details as a payment token, handle the
cardTokenized
event in the checkout.com Frames integration. The token is returned in the token
property of the event.Completing funding source setup with provider specific data
Once the provider-specific data has been obtained, construct a provider specific completion data object and call the
completeFundingSource
method to finish the process of provisioning a funding source:The
completeFundingSource
call accepts an optional updateCardFundingSource
parameter (default value is true). This parameter is a flag to indicate whether to automatically update unfunded cards' funding source when a new funding source is created:// For Stripe
const completionData: CompleteFundingSourceStripeCardCompletionDataInput = {
provider: 'stripe',
type: FundingSourceType.CreditCard,
paymentMethod: setupIntentPaymentMethodAsString, // Retrieve from Stripe API
}
// For Checkout.com
const completionData: CompleteFundingSourceCheckoutCardCompletionDataInput = {
provider: 'checkout',
type: FundingSourceType.CreditCard,
paymentToken: paymentTokenReturnedFromFrames, // Retrieve from Checkout.com API
}
try {
const fundingSource = await virtualCardsClient.completeFundingSource({
id: provisionalFundingSource.id,
completionData,
// Optional flag to indicate whether to automatically update unfunded cards' funding source when a new funding source is created (defaults to true)
updateCardFundingSource: true,
} catch (error) {
if (error instanceof FundingSourceRequiresUserInteractionError) {
// Handle additional user interaction
}
else {
// Handle error
}
}
try {
let provisionalFundingSource = try await virtualCardsClient.setupFundingSource(
withInput: SetupFundingSourceInput(
type: .creditCard,
currency: "USD",
// include only the provider(s) you will support
supportedProviders: ["stripe", "checkout"]
)
)
} catch {
// Handle/notify user of errors
}
The call to
setupFundingSource
will return a ProvisionalFundingSource
containing provisioning data required to continue the funding source creation process. To continue, you must use either the Stripe API or the checkout.com API to progress the funding source setup; the chosen provider must match that returned in the ProvisionalFundingSource.provisioningData
property.Retrieve the provider API key as well as other information pertaining to the funding source provider using the
getFundingSourceClientConfiguration
method and finding the client configuration for your supported provider(s): try {
val configuration = withContext(Dispatchers.IO) {
virtualCardsClient.getFundingSourceClientConfiguration()
}
// [configuration] contains the list of funding source client configuration.
} catch (e: FundingSourceException) {
// Handle/notify user of exception
}
}
Stripe Funding Source Preparation
For Stripe iOS-Swift, see the documentation at:
To create a Stripe setup intent, call
STPAPIClient.confirmSetupIntent(with:)
and ensure that the
STPSetupIntentConfirmParams
is populated with the card that is to be added as a funding source.Card and Billing Details are required.
checkout.com Funding Source Preparation
For checkout.com iOS-Swift, see the documentation at:
To create a payment token in checkout.com, call
CheckoutApiClient.createCardToken(card: CkoCardTokenRequest)
and ensure that the CkoCardTokenRequest
input parameter is populated with card details and billing details that you wish to add as a funding source.Card and Billing Details are required.
Completing funding source setup with provider specific data
Once the provider-specific data has been obtained, construct a provider specific completion data object and call the
completeFundingSource
method to finish the process of provisioning a funding source:/// Stripe
let completionData = StripeCompletionDataInput(
paymentMethodId: paymentMethodId // This is the payment method identifier of the Stripe SetupIntent success response.
)
/// OR
/// checkout.com
let completionData = CheckoutCompletionDataInput(
paymentToken: paymentToken // This is the payment token returned in the CkoCardTokenResponse returned by createCardToken
)
try {
let fundingSource = try await virtualCardsClient.completeFundingSource(
withInput: CompleteFundingSourceInput(
id: id, // This is the identifier of the provisional Funding Source.
completionData: completionData
)
)
} catch {
// Handle/notify user of errors
}
launch {
try {
val setupInput = SetupFundingSourceInput(
"USD",
FundingSourceType.CREDIT_CARD,
// include only the provider(s) you will support
listOf("stripe", "checkout")
val provisionalFundingSource = withContext(Dispatchers.IO) {
virtualCardsClient.setupFundingSource(
setupInput
)
}
// The returned [provisionalFundingSource] has been created.
} catch (e: FundingSourceException) {
// Handle/notify user of exception
}
}
The call to
setupFundingSource
will return a ProvisionalFundingSource
containing provisioning data required to continue the funding source creation process. To continue, you must use either the Stripe API or the checkout.com API to progress the funding source setup; the chosen provider must match that returned in the ProvisionalFundingSource.provisioningData
property.Retrieve the provider API key as well as other information pertaining to the funding source provider using the
getFundingSourceClientConfiguration
method:launch {
try {
val configuration = withContext(Dispatchers.IO) {
virtualCardsClient.getFundingSourceClientConfiguration()
}
// [configuration] contains the list of funding source client configuration.
} catch (e: FundingSourceException) {
// Handle/notify user of exception
}
}
Stripe Funding Source Preparation
For Stripe Android-Kotlin, see the documentation at:
To setup a setup intent in Stripe, call
StripeClient.confirmSetupIntent(confirmSetupIntentParams: ConfirmSetupIntentParams)
and ensure that the ConfirmSetupIntentParams
input parameter is populated with card details and billing details that you wish to add as a funding source.Card and Billing Details are required.
checkout.com Funding Source Preparation
For checkout.com Android-Kotlin, see the documentation at:
To create a payment token in checkout.com, call
CheckoutApiClient.generateToken(cardTokenisationRequest: CardTokenisationRequest)
and ensure that the CardTokenisationRequest
input parameter is populated with card details and billing details that you wish to add as a funding source.Card and Billing Details are required.
Completing funding source setup with provider specific data
Once the provider-specific data has been obtained, construct a provider specific completion data object and call the
completeFundingSource
method to finish the process of provisioning a funding source:launch {
try {
val completionData = StripeCardProviderCompletionData(
paymentMethodId // This is the payment method identifier of the Stripe SetupIntent success response.
)
/** OR ***/
val completionData = CheckoutCardProviderCompletionData(
paymentToken // This is the payment token returned from the checkout.com generateToken call.
)
val completeInput = CompleteFundingSourceInput(
provisionalFundingSource.id,
completionData,
null
)
val fundingSource = withContext(Dispatchers.IO) {
virtualCardsClient.completeFundingSource(
completeInput
)
}
// The returned [fundingSource] has been created.
} catch (e: FundingSourceException) {
// Handle/notify user of exception
}
}
The
completeFundingSource
method can throw a FundingSourceRequiresUserInteraction
exception. This indicates that further interaction with the user is required before the funding source setup process can be completed.The thrown exception contains data indicating what action needs to be taken along with the source of the interaction requirement. The need for further interaction can arise because a particular payment processor needs to perform strong authentication (for example 3DS2). The requirement to handle this case is dependent on which provider(s) you are supporting in your application.
The following table indicates the types of user interaction that may be returned and how they should be handled:
Interaction type | Identification | Action to take | Completion process |
---|---|---|---|
Checkout.com strong authentication | Interaction data type is CheckoutCardInteractionData | Mobile applications should launch a web view targeting the URL specified in the redirectUrl property of the interaction data contained in the error.
Web applications should navigate to the URL specified in the redirectUrl property of the interaction data contained in the error. | Call completeFundingSource again, on successful completion of the authentication, with the same payment token as used in the first call. |
If there is any failure returned from the payment processor (Stripe or Checkout.com) prior to calling
completeFundingSource
, then the provisional funding source returned by setupFundingSource
method may be re-used for multiple attempts at completeFundingSource
.Examples of failures include the user entering incorrect expiry, billing address or security code information for a card.
If a user decides they want to remove a funding source from their account, the ability to provide them with the means to do so is applied with the
cancelFundingSource
method.When a funding source is cancelled, any associated active virtual cards will no longer be able to process transactions. Any such transactions will be declined.
This API call is idempotent, so any subsequent calls to this method with the same
id
will always yield the same result.When a funding source is cancelled, the record of the funding source will not be deleted, but instead its state will be set to
INACTIVE
and will no longer be usable for provisioning virtual cards. This is because refunds are always returned to the same original funding source and so clients will need to be able to retain details about cancelled funding in case any such future refunds refer to them.TypeScript
Swift
Kotlin
// Collect the input id however makes sense for your implementation.
// const fundingSourceId = fundingSource.id
try {
const fundingSource = await virtualCardsClient.cancelFundingSource(
fundingSourceId
)
// The returned `fundingSource` is now cancelled and in an INACTIVE state.
} catch {
// Handle/notify user of errors
}
do {
// Retrieve the id for canceling the funding source.
let fundingSource = try await self.virtualCardsClient.cancelFundingSource(withId: id)
// The returned funding source is now cancelled.
} catch {
// Handle/notify user of error
}
// Collect the input id however makes sense for your implementation.
// val fundingSourceId = fundingSource.id
try {
val fundingSource = withContext(Dispatchers.IO) {
virtualCardsClient.cancelFundingSource(fundingSourceId)
}
// The returned [fundingSource] is now cancelled.
} catch (e: FundingSourceException) {
// Handle/notify user of exception
}
Bank account funding sources may periodically require the user to re-authorize access to them or for the user to login again. When this is necessary, the funding source will be changed to a
REFRESH
state. Funding sources requiring a refresh continue to be usable in a limited manner; virtual cards backed by these funding sources may be used for transactions but no new virtual cards will be available. Commonly, requiring a refresh is a precursor to the funding source being cancelled by the provider and so action should be taken in a reasonable time frame to restore such funding sources.In order to restore a funding source to a fully usable, active state, clients should refresh any such funding sources using the
refreshFundingSource
method.Typescript
try {
const fundingSource = await virtualCardsClient.refreshFundingSource({
id: fundingSourceId,
refreshData: providerSpecificRefreshData,
})
} catch (error) {
if (error instanceof FundingSourceRequiresUserInteractionError) {
// Handle additional user interaction
}
else {
// Handle error
}
}
As with
completeFundingSource
, the refreshFundingSource
method can throw a FundingSourceRequiresUserInteraction
exception. This indicates that further interaction with the user is required before the funding source refresh process can be completed.The thrown exception contains data indicating what action needs to be taken along with the source of the interaction requirement. The need for further interaction can arise because a particular payment processor needs to perform separate authentication (for example OAuth). The requirement to handle this case is dependent on which provider(s) you are supporting in your application.
The following table indicates the types of user interaction that may be returned and how they should be handled:
Interaction type | Identification | Action to take | Completion process |
---|---|---|---|
Plaid bank account authentication and linkage. | Interaction data type is CheckoutBankAccountRefreshFundingSourceInteractionData | Mobile and web applications should invoke Plaid Link, providing the token specified in the linkToken property of the interaction data contained in the error.
The user must then enter their credentials to complete the authentication with their financial institution. | Call refreshFundingSource again, on successful completion of the Link, providing authentication data as with completeFundingSource . |
Previously created (or cancelled) funding sources can be accessed in two ways: via its identifier (Single Funding Source by Id), or via a list method (List Funding Sources).
A fetch of single or multiple funding sources can be performed remotely or locally by specifying the appropriate CachePolicy as part of the input.
To retrieve a single funding source given its unique
id
, use the getFundingSource
method. This method will return the record in an active or inactive state if it exists.TypeScript
Swift
Kotlin
try {
const fundingSource = await virtualCardsClient.getFundingSource({
id,
cachePolicy: CachePolicy.RemoteOnly,
})
// `fundingSource` contains the fundingSource object, else `undefined` if not found.
} catch {
// Handle/notify user of errors
}
do {
let fundingSource = try await self.virtualCardsClient.getFundingSource(
withId: id,
cachePolicy: .remoteOnly
)
// If the id matches a funding source, `fundingSource` will be returned, else nil.
} catch {
// Handle/notify user of error
}
launch {
try {
val fundingSource = withContext(Dispatchers.IO) {
virtualCardsClient.getFundingSource(
id,
cachePolicy = CachePolicy.REMOTE_ONLY
)
}
// If the [id] matches a funding source, [fundingSource] will be returned, else [null].
} catch (e: FundingSourceException) {
// Handle/notify user of exception
}
}
The ability to retrieve multiple or all funding sources available to the user is supported. The results can be paginated and can contain funding sources which may be active whilst others are inactive.
A call to a list API will return a
ListOutput
object containing a list of matching items
and a nextToken
to support pagination. If no results matching the input are found, the result will contain empty items.TypeScript
Swift
Kotlin
try {
const listOutput = await virtualCardsClient.listFundingSources({
cachePolicy: CachePolicy.RemoteOnly,
limit: 20,
nextToken,
})
// `listOutput.items` contains the list of items matching the input.
// Page through the results if `listOutput.nextToken` != undefined.
} catch {
// Handle/notify user of errors
}
do {
let listOutput = try await self.virtualCardsClient.getFundingSources(
withLimit: 20,
nextToken: nextToken,
cachePolicy: .remoteOnly
)
// `listOutput.items` contains the list of items matching the input.
// Page through the results if `listOutput.nextToken` != nil.
} catch {
// Handle/notify user of error
}
launch {
try {
val listOutput = withContext(Dispatchers.IO) {
virtualCardsClient.listFundingSources(
limit = 20,
nextToken = nextToken,
cachePolicy = CachePolicy.REMOTE_ONLY
)
}
// [listOutput.items] contains the list of items matching the input.
// Page through results if [listOutput.nextToken] != null.
} catch (e: FundingSourceException) {
// Handle/notify user of exception
}
}
Consumers of the SDK may choose to subscribe to notifications of changes to Funding Sources from the Sudo Platform rather than polling. This is done via the
subscribeToFundingSourceChanges
method. Subscribing is done across all Funding Sources associated with the client, not on a per-funding-source basis.This method accepts a unique subscription identifier and a subscriber object which must implement the
fundingSourceChanged(fundingSource: FundingSource): Promise<void>
method. This handler should contain application-specific implementation of behavior in the event of a funding source change.Typescript
await instanceUnderTest.subscribeToFundingSourceChanges(
'subscription-id',
{
fundingSourceChanged(fundingSource: FundingSource): Promise<void> {
// Implement handling for funding source changed behaviour
},
},
)
If the
subscribeToFundingSourceChanges
method is called more than once with the same subscription id, subsequent invocations will replace the earlier subscriptions.Once no longer interested in funding source changes, clients may unsubscribe by calling the
unsubscribeFromFundingSourceChanges
method, passing the same subscription identifier.Typescript
sudoVirtualCardClient.unsubscribeFromFundingSourceChanges(
'subscription-id'
)
Last modified 9d ago