Introduction
Welcome to the Prepaid2Cash Partner API.
The Prepaid2Cash Partner API opens the full range of P2C prepaid card services to registered Partners, including:
- Cash redemption of customer prepaid cards (open and closed loop)
- Payout to customer via ACH, push to debit, or Partner disbursement channels
- Balance transfer into customer's account with Partner
- Multilevel fraud prevention, including full KYC and OFAC verification
We offer mobile SDKs for iOS and Android, or you can integrate directly to our REST API.
Navigating this Document
Primary content and API documentation is in this middle column. The right-hand column contains corresponding API request and response samples.
Use the left-hand column navigation to quickly jump to any section of the documentation, or to search all sections.
Basics
Prepaid Debit Cards
The Prepaid2Cash API can be used to redeem both Open Loop and Closed Loop prepaid debit cards.
Open Loop prepaid debit cards are accepted at most merchants, and are typically branded with a Visa, Mastercard, American Express, or Discover logo. These cards are also known as "network-branded" cards, or generically as "prepaid" cards.
Closed Loop prepaid debit cards are only accepted by the merchant which issued the card (or an affiliate). These cards have merchant branding, do not have a network logo, and are commonly called "store cards", or "gift cards".
Environments
Prepaid2Cash operates multiple API environments. API keys are issued separately for each environment.
Production
🔵 Production Base URL
https://api.prepaid2cash.com/
The Production environment is our "live" environment. Transaction data is sent to processing networks for capture and disbursement of real funds.
Sandbox
🔵 Sandbox Base URL
https://sandbox.api.prepaid2cash.com/
The Sandbox environment is used to test integrations with Prepaid2Cash in a non-production environment. API requests to the Sandbox environment will not send transaction data to processing networks, so will never transfer funds to or from live prepaid cards.
Authentication
🔵 HTTP Authorization Header
Authorization: pk_test_ImlkX2Zvcm0iOiJkcml
Access to the Prepaid2Cash Partner API requires an API key. To request an API key, contact Prepaid2Cash support.
All requests to the Prepaid2Cash Partner API must include your API key in the Authorization
HTTP header, as shown in the right-hand column.
Monetary Amounts
✅ OK ($26.00 USD)
{ "amount": 2600 }
Monetary amounts in the Prepaid2Cash API are always specified in USD, and always expressed as an integer representation of the smallest denomination of the currency, i.e. USD cents.
Timestamps
✅ OK
{ "created_at": "2019-07-04T00:00:00Z" }
Timestamps are always specified in UTC, and always represented in ISO 8601 format, except where superseding protocols specify otherwise (e.g. JSON Web Tokens).
Idempotency
The API supports idempotency for safely retrying requests without accidentally performing the same operation twice. This is useful when an API call is disrupted in transit and you do not receive a response. For example, if a request to create a transaction does not respond due to a network connection error, you can retry the request with the same idempotency key to guarantee that only one transaction is created.
🔵 HTTP Idempotency-Key Header
Idempotency-Key: b0defbc9-a53f-4534-b969-48cfcc39fd4d
To perform an idempotent request, include an Idempotency-Key
header in your request.
An idempotency key is a unique value generated by the API client. We suggest using V4 UUIDs.
Errors
The API returns conventional HTTP response codes to indicate the results of each request.
Generally, response codes in the 4xx
range indicate an error with submitted data, and the 5xx
range indicates a server error.
When additional error information is available (e.g. most 400
and 422
responses), it will be included in the response object.
Mobile SDKs
Prepaid2Cash Mobile SDKs are available for iOS and Android. Each SDK has demo app and sample integration code.
- Prepaid2Cash UI SDK is the quickest way to get up and running. The UI SDK presents the full user flow to collect card and customer details, submit transactions to the P2C API, and retrieve transaction results.
- Prepaid2Cash Core SDK is the best choice if you need greater customization controls over the flow and views in your app. The Core SDK handles all aspects of the P2C protocol, including encryption and token signature verification, but leaves the design decisions to you.
We'll take a closer look at the Prepaid2Cash Mobile SDKs in the integration guides below.
Create a Partner Account
Contact Prepaid2Cash support to set up your Partner Account.
Android
Downloads
- Android SDK Demo App (requires Partner Account)
- Maven Repository (requires Partner Account)
Requirements
- Android 5.0 (API level 21) and above
- Android Gradle Plugin 3.3.1+
- Gradle 4.10.1+
- Prepaid2Cash Partner Account
Configure Repositories
allprojects {
repositories {
maven {
url 'https://developer.prepaid2cash.com/maven2'
credentials {
username "yourusername"
password "yourpassword"
}
}
maven { url 'https://jitpack.io' }
}
}
In your root-level (project-level) Gradle file, add maven repositories for Prepaid2Cash and JitPack.
Customize the Card Reader View
colors.xml
<color name="p2c_color_primary">#71c05e</color>
strings.xml
<string name="p2c_card_scan_text">Hold your card here.\nIt will scan automatically.</string>
The appearance of the card reader view is configurable with custom colors, instructional text, and logo. Modifications can be made in the following files:
res/values/colors.xml
- Set attribute
p2c_color_primary
with your primary view color
res/values/strings.xml
- Set attribute
p2c_card_scan_text
with your instructional text
res/drawable-*/p2c_card_reader_logo.png
- Replace these drawable files with your logo images
UI SDK
The Prepaid2Cash UI SDK contains the full flow required to create a transaction with a prepaid debit card. It requires just a few lines of code to integrate into your mobile app.
Add Dependencies
dependencies {
implementation 'com.prepaid2cash:Prepaid2CashUISDK:0.6.1'
}
In your module (app-level) Gradle file, add com.prepaid2cash
to your build.gradle
dependencies.
Launch the Flow
Kotlin
val apiKey = "pk_test_your_api_key"
val UAT = "your_user_authorization_token"
val productionFlag = false
startActivity(Prepaid2CashActivity.getStartIntent(context, apiKey, UAT, productionFlag))
Java
String apiKey = "pk_test_your_api_key";
String UAT = "your_user_authorization_token";
boolean productionFlag = false;
startActivity(Prepaid2CashActivity.Companion.getStartIntent(this, apiKey, UAT, productionFlag));
The Prepaid2CashActivity
class is the entry-point to the Prepaid2Cash SDK. It must be initialized with an API Key.
To create users and transactions, you will need to provide a User Authorization Token.
Process Transaction Results
The SDK will return a Transaction Results Token, which can be used to display results in your mobile app, and sent to your API for verification and processing.
Core SDK
The Prepaid2Cash Core SDK contains the essential methods to access the P2C API, making it easy to integrate into your app's existing flow and design.
Add Dependencies
dependencies {
implementation 'com.prepaid2cash:Prepaid2CashSDK:0.1.4'
}
In your module (app-level) Gradle file, add com.prepaid2cash
to your build.gradle
dependencies.
Initialization
val yourSecretKey = "pk_test_your_api_key"
val isProduction = false
Prepaid2Cash.initApp(yourSecretKey, isProduction)
The first step is to initialize the SDK, using your API key.
To create a transaction, choose the Prepaid flow for Open Loop cards, or the GiftCard flow for Closed Loop cards.
Both flows require a User Authorization Token.
Core SDK, Open Loop Transaction
Card Data Entry via Optical Scan/OCR
Card Data Entry via Optical Scan/OCR
startActivityForResult(ScanCardActivity.getStartIntent(this), 123)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 123) {
if (resultCode == Activity.RESULT_OK) {
val cardNumber = data?.getStringExtra(Prepaid2Cash.EXTRA_CARD_NUMBER)
val cardType = data?.getStringExtra(Prepaid2Cash.EXTRA_CARD_TYPE)
val byteArray = data?.getByteArrayExtra(Prepaid2Cash.EXTRA_BYTE_ARRAY)
} else if (resultCode == Activity.RESULT_CANCELED) {
Log.e(TAG, "ERROR")
}
}
}
The Prepaid2Cash Mobile SDKs include a card scanner to identify and read card data through your customer's phone camera.
To launch the scanner, simply start the activity ScanCardActivity
, calling it with startActivityForResult
.
After successfully scanning the card, you'll receive the result, overriding the onActivityResult
method and reading the values from the Intent.
cardNumber
and cardType
will be used in the next step.
Start a Prepaid Card (Open Loop) Transaction
Start a Prepaid Card (Open Loop) Transaction
val UAT = "your_user_authorization_token"
val prepaidCard = Prepaid2CashPrepaidCard.withUAT(UAT)
prepaidCard?.processTransactionData(
amount = amount,
pan = cardNumber,
expiryMonth = expiryMonth,
expiryYear = expiryYear,
cvv = cvv,
description = cardType,
prepaidCardImageByteArray = byteArray,
isOCR = true,
listener = object : ResponseListener<RenderPrepaidTransaction> {
override fun onSuccessfulResponse(response: RenderPrepaidTransaction) {
}
override fun onErrorResponse(error: Throwable) {
}
}
)
Before starting a new open loop transaction, it will be necessary to collect some transaction data from the customer:
- Transaction Amount
- Expiry Month
- Expiry Year
- CVV
We recommend performing basic validation on this data before proceeding.
The RenderPrepaidTransaction
object will contain transaction details for the customer to confirm, e.g. payout amount and estimated delivery. The full response data is documented at Create Open Loop Transaction
Confirm Transaction
Confirm Transaction
Prepaid2CashPrepaidCard.withUAT(UAT)?.saveTransactionData(
listener = object : ResponseListener<String>{
override fun onSuccessfulResponse(response: String) {
}
override fun onErrorResponse(error: Throwable) {
}
}
)
The next step is to confirm and submit the transaction.
Process Transaction Results
The SDK will return a Transaction Results Token, which can be used to display results in your mobile app, and sent to your API for verification and processing.
Core SDK, Closed Loop Transaction
Fetch Merchants list
Fetch Merchants list
Prepaid2CashGiftCard.withUAT(UAT)?.getMerchants(
listener = object : ResponseListener<List<String>> {
override fun onSuccessfulResponse(response: List<String>) {
}
override fun onErrorResponse(error: Throwable) {
}
}
)
The first step in creating a new closed loop transaction is to fetch the list of active Gift Card merchants. The active list generally includes 80-120 merchants, and changes regularly.
Fetch ID Types list
Fetch ID Types list
Prepaid2CashGiftCard.withUAT(UAT)?.getIdTypes(
listener = object : ResponseListener<List<String>> {
override fun onSuccessfulResponse(response: List<String>) {
}
override fun onErrorResponse(error: Throwable) {
}
}
)
Next, we fetch the list of valid ID types. This list is static, and does not require a network request.
Start a Gift Card (Closed Loop) Transaction
Start a Gift Card (Closed Loop) Transaction
Prepaid2CashGiftCard.withUAT(UAT)?.processGiftCardInfo(
merchantName = merchantName,
pan = giftCardNumber,
pin = pinNumber,
idDescription = idType,
idNumber = idNumber,
listener = object : ResponseListener<RenderGiftCardTransaction> {
override fun onSuccessfulResponse(response: RenderGiftCardTransaction) {
}
override fun onErrorResponse(error: Throwable) {
}
}
)
After fetching the Merchant and ID types lists, we can begin to collect the transaction data from the customer:
- Merchant
- User's Photo ID Type (Driver License, Passport, etc)
- User's Photo ID Number
- Card PAN
- Card PIN (not required for all cards)
It is not necessary to submit a transaction amount for closed loop cards -- this will be retrieved from the merchant.
We recommend performing basic validation on the transaction data before proceeding.
Prepaid2Cash will attempt to find an offer to purchase the customer's closed loop card. If successful, the offer details, including payout amount and estimated delivery, should be presented to the customer to accept or decline.
The RenderGiftCardTransaction
object will contain transaction details. The full response data is documented at Create Closed Loop Transaction
Accept Offer
Accept Offer
Prepaid2CashGiftCard.withUAT(UAT)?.submitGiftCard(
listener = object : ResponseListener<String> {
override fun onSuccessfulResponse(response: String) {
}
override fun onErrorResponse(error: Throwable) {
}
}
)
If the customer accepts the offer, call submitGiftCard
to confirm.
Decline Offer
Decline Offer
Prepaid2CashGiftCard.withUAT(UAT)?.declineGiftCard(
listener = object : ResponseListener<String> {
override fun onSuccessfulResponse(response: String) {
}
override fun onErrorResponse(error: Throwable) {
}
}
)
If the customer declines the offer, call declineGiftCard
to close the transaction.
Process Transaction Results
If the customer has accepted the offer, the SDK will return a Transaction Results Token, which can be used to display results in your mobile app, and sent to your API for verification and processing.
iOS
Downloads
- iOS SDK Demo App Project (requires Partner Account)
- CocoaPods Repository (requires Partner Account)
Requirements
- iOS 10 or later
- Xcode 11 or later
- CocoaPods
- Prepaid2Cash Partner Account
UI SDK
The Prepaid2Cash UI SDK contains the full flow required to create a transaction with a prepaid debit card. It requires just a few lines of code to integrate into your mobile app.
The UI flow is implemented in 5 steps:
- Set API Key
- Set User Authorization Token (UAT)
- Set Delegate
- Present Flow
- Process Transaction Results
Set API Key
Prepaid2CashSDK.config(apiKey: "pk_test_your_api_key")`
Configure in your AppDelegate, in didFinishLaunchingWithOptions
.
Set User Authorization Token (UAT)
let myUAT = "my_user_authorization_token"
Prepaid2CashSDK.config(uat: myUAT)
The User Authorization Token should be generated and signed by your backend. More about UATs.
Set Delegate
public protocol P2CTransactionDelegate {
func transactionFinishedSuccess(jwt: String)
func transactionFinishedWithError(error: Error?)
func transactionEvent(event: P2CEvent)
}
Prepaid2CashSDK.shared().delegate = self
Delegate needs to be set to a class that conforms to the expected protocol.
Present Flow
Prepaid2CashSDK.launch(navigationController: navigationController!)
The final step of the UI flow is to present the SDK view.
When the SDK flow completes, your app will return to the original presenting view.
Process Transaction Results
The SDK will return a Transaction Results Token, which can be used to display results in your mobile app, and sent to your API for verification and processing.
Core SDK
The Prepaid2Cash Core SDK contains the essential methods to access the API, making it easy to integrate into your app's existing flow and design.
Core SDK, Open Loop Transaction
For Prepaid Cards, follow these steps:
- Set Scanner Delegate
- Scan Card Using Prepaid2Cash OCR Library
- Collect Additional Card Data
- Retrieve and Select Payout Options
- Create Transaction
- Process Transaction Results
Set Scanner Delegate
Prepaid2CashSDK.shared().scannerDelegate = self
Scan Card Using Prepaid2Cash OCR Library
Prepaid2CashSDK.launchCardScannerForPrepaidTransaction(from: self)
The delegate method will receive a masked version of the card number for display in your UI.
public func scannerResult(success: Bool, maskedCardNumber: String?)
Collect Additional Card Data
cvv
is the card verification code (3 or 4 digit string, e.g.123
)expirationDate
(normalize to MM/YY format, e.g.05/25
)cardAmount
(normalize to integer USD cents, e.g.10000
for $100.00)
Retrieve and Select Payout Options
let cvv = "123"
let expirationDate = "05/25"
let cardAmount = 10000
Prepaid2CashSDK.getPayoutOptions(amount: cardAmount, cardSubtype: .open_loop, completion: { options in
// Handle OK
}, failure: { error in
// Handle Error
})
The API response will include the payout amount for each payout option.
Create Transaction
Prepaid2CashSDK.createPrepaidCardTransaction(amount: cardAmount, cvv: cvv, expirationDate: expirationDate, payoutOption: selectedOption, completion: { transactionResult in
// Clear Scanner after successful or failed transaction
Prepaid2CashSDK.clearScanner()
print("Transaction result: \(transactionResult.value)")
}, failure: { error in
// Handle Error
})
Process Transaction Results
func transactionFinishedSuccess(jwt: String)
The SDK will return a Transaction Results Token, which is a signed JWT containing the details of transaction results.
This token can be decoded to display transaction results in your mobile app, and can be sent to your backend API for verification and processing.
The TRT will be returned through the delegate at the end of the transaction process.
Core SDK, Closed Loop Transaction
For Gift Cards, follow these steps:
- Get Active Merchant List
- Collect Card Data
- Retrieve Payout Options
- Create Transaction
- Display Offer to User
- Accept or Decline Offer
- Process Transaction Results
Get Active Merchant List
Prepaid2CashSDK.getMerchantList(completion: { merchantList in
// Handle OK
}), failure: { error in
// Handle Error
})
Collect Card Data
merchant
is selected from list in prior stepgiftCardNumber
is the Primary Account Number (PAN) of the cardgiftCardPin
is the PIN or verification code (not present on all cards)
Retrieve Payout Options
let merchant = merchantList.first!
let giftCardNumber = "9111111111111106"
let giftCardPin = "2749"
// Retrieve and select payout option
Prepaid2CashSDK.getPayoutOptions(bin: giftCardNumber, amount: nil, cardSubtype: .closed_loop, completion: { options in
// Handle OK
}), failure: { error in
// Handle Error
})
Create Transaction
Prepaid2CashSDK.createGiftCardTransaction(cardNumber: giftCardNumber, cardPin: giftCardPin, payoutOption: selectedOption, merchant: merchant, completion: { transaction in
// Handle OK
}), failure: { error in
// Handle Error
})
Display Offer to User
Accept or Decline Offer
// Accept Offer
Prepaid2CashSDK.acceptGiftCardTransaction(transaction: currentTransaction, completion: { transactionResult in
print("Transaction result: \(transactionResult.value)")
}, failure: { error in
// Handle Error
})
// Decline Offer
Prepaid2CashSDK.declineGiftCardTransaction(transaction: currentTransaction, completion: { transactionResult in
// Handle OK
}, failure: { error in
// Handle Error
})
Process Transaction Results
func transactionFinishedSuccess(jwt: String)
The SDK will return a Transaction Results Token, which is a signed JWT containing the details of transaction results.
This token can be decoded to display transaction results in your mobile app, and can be sent to your backend API for verification and processing.
The TRT will be returned through the delegate at the end of the transaction process.
REST API
The Prepaid2Cash Partner API is a RESTful API, which accepts and returns JSON-encoded data, and uses standard HTTP verbs, response codes, and authentication.
If you don't need the features offered by our Mobile SDKs, you can integrate directly via our REST API.
Functional Flows
New Open Loop Transaction
Open Loop ("prepaid card") transactions attempt to debit the user's prepaid card. If successful, funds are captured immediately and paid out to customer, or transferred to Partner for funding or payout, as specfied in Partner agreement.
Open Loop transactions can be created in two or three steps:
- Create User (Direct API-API integration only, optional)
- Retrieve Transaction Options by submitting initial transaction data.
- Create Open Loop Transaction after user has confirmed the full transaction details, including payout amount and estimated delivery.
New Closed Loop Transaction
Closed Loop ("gift card") transactions attempt to purchase the user's card for inventory sales into a secondary market. If the card is purchaseable, an offer is returned to the customer for approval. If approved, the card is purchased and proceeds are paid out to customer, or transferred to Partner for funding or payout, as specfied in Partner agreement.
Closed Loop transactions can be created in four or five steps:
- Create User (Direct API-API integration only, optional)
- Retrieve Closed Loop Merchants for the list of active gift card merchants. This list changes regularly due inventory fluctuation.
- Retrieve Transaction Options by submitting initial transaction data.
- Create Closed Loop Transaction by submitting full gift card data.
- Accept Closed Loop Offer after user has approved the sale amount.
API Endpoint Reference
Create User
This endpoint creates a new user record. It returns the new user ID and an SMS verification code which has been sent to the user's phone. This code will be required to submit a transaction, and we also recommend verifying this code in your interaction flow.
If identifying user details match an existing Partner user, a new record will not be created, and the existing user ID will be returned instead.
In both cases, a new SMS verification code will be sent, and included in the response.
If your application requires customers to scan a photo ID, you may send
raw PDF417 data (AAMVA standard, 2005 or newer) in the id_pdf417
field.
If included, only additional fields phone
and email
are required.
Contact us to enable this feature for your partner account.
HTTP Request
POST https://api.prepaid2cash.com/v2/users
Request Body Fields
⏩ Request (PDF417 plus required and optional fields)
POST /v2/users HTTP/1.1
Host: api.prepaid2cash.com
Authorization: pk_test_ImlkX2Zvcm0iOiJkcml
{
"id": "d54747d1-2993-4bdc-a745-321f7f33e8af",
"phone": "+1 415-456-1000",
"email": "norton@sf.ca.us",
"id_pdf417": "@\n\u001e\rANSI 636004080002DL00410266ZN03070017DLDAQ123456789123\nDCSNORTON\nDDEN\nDACJOSHUA\nDDFN\nDAD\nDDGN\nDCAC\nDCBNONE\nDCDNONE\nDBD02041976\nDBB08151987\nDBA08152020\nDBC2\nDAU070 in\nDAYBRO\nDAG624 COMMERCIAL STREET\nDAISAN FRANCISCO\nDAJCA\nDAK941111010\nDCF0123456789\nDCGUSA\nDAZBRO\nDCLU \nDCK000012345678NCSVTL01\nDDB10242014\nDDK1\nDDL1\nZNZNADUP\nZNB\nZNC0\n",
"user_photo": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaAQMAAACThN6NAAAAA1BMVEUV2wDfW0CVAAAAC0lEQVQIHWMYcAAAAIIAAbfUbfMAAAAASUVORK5CYII="
}
Field | Type | Description |
---|---|---|
id | string | User ID, unique in Partner domain (optional) |
phone | string | Telephone number with country code, ITU-T E.123 format, hyphens optional |
string | Email address | |
id_pdf417 | string | Raw PDF417 2D barcode data (AAMVA standard) (optional) |
user_photo | string | Base64 encoded image data (PNG, JPG, BMP) (optional) |
✅ Response (Created)
201 Created
{
"id": "e8379ab7-fe92-4ad0-b25e-6ba4ddb0999f",
"verification_code": "12345"
}
✅ Response (OK, Found)
200 OK
{
"id": "e8379ab7-fe92-4ad0-b25e-6ba4ddb0999f",
"verification_code": "12345"
}
Retrieve Transaction Options
This endpoint returns the options and requirements needed to create a new Open Loop transaction. The request includes preliminary transaction data. Options returned may be presented to the prepaid card customer for selection, or may be selected by Partner policy.
HTTP Request
POST https://api.prepaid2cash.com/v2/transaction_options
Request Body Fields
⏩ Request
POST /v2/transaction_options HTTP/1.1
Host: api.prepaid2cash.com
Authorization: pk_test_ImlkX2Zvcm0iOiJkcml
{
"amount": 10000,
"prepaid_card": {
"card_subtype": "open_loop",
"bin": "411111"
},
"user_id": "e8379ab7-fe92-4ad0-b25e-6ba4ddb0999f",
"user_authorization": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilo2WkZTZXdENEZZYXlqOFNvV1JDX0VBcngxTSIsIng1dCI6Ilo2WkZTZXdENEZZYXlqOFNvV1JDX0VBcngxTSIsIng1dCNTMjU2Ijoickp2eXZOZGFEOEk1V293bmM3ZnhMMTlQS0NFREsxWGxyMHpYQndhMGxHUSJ9.eyJpc3MiOiJwYXJ0bmVyZG9tYWluLmNvbSIsImF1ZCI6InByZXBhaWQyY2FzaC5jb20iLCJpYXQiOjE1Nzc4MzY4MDAsImV4cCI6MjU3NzgzNjgwMCwiaHR0cDovL3AyYy5pby91c2VyIjp7ImlkIjoiZDU0NzQ3ZDEtMjk5My00YmRjLWE3NDUtMzIxZjdmMzNlOGFmIiwiZmlyc3RfbmFtZSI6Ikpvc2h1YSIsImxhc3RfbmFtZSI6Ik5vcnRvbiIsImFkZHJlc3MxIjoiNjI0IENvbW1lcmNpYWwgU3QiLCJhZGRyZXNzMiI6IiIsImNpdHkiOiJTYW4gRnJhbmNpc2NvIiwic3RhdGUiOiJDQSIsImNvdW50cnkiOiJVUyIsInBvc3RhbF9jb2RlIjoiOTQxMTEtMTAxMCIsInBob25lIjoiKzEgNDE1LTQ1Ni0xMDAwIiwiZW1haWwiOiJub3J0b25Ac2YuY2EudXMiLCJkb2IiOiIxOTc2LTAyLTA0Iiwic3NuX2xhc3RfNCI6IjE3NzYiLCJpZF9mb3JtIjoiZHJpdmVyc19saWNlbnNlIiwiaWRfaXNzdWVyIjoiVVMvQ0EiLCJpZF9udW1iZXIiOiJEMTIzNDU2NzgiLCJreWNfdmVyaWZpZWQiOlsiZmlyc3RfbmFtZSJdfX0.nbywUp4vkQ8uCphzpykrDm7jLHMl8Ixt9DJPIhWQQo7RYbIV6lmr4EwOWCg_TNcjf7l4jNhd33daD1qeCSNxpKMUs45joJlVKFPnjiu32PGNzfOdRw28ElWVCXzQOTR5_OLoRvx6xX_oIOQI9FuMlHyoNq9G6hBpM1zOey74GYunO6WNJPbDjh5bUpZB9L4z_OPs3SgzKzpOuTOLS7tBiiJsgHyS8pex4-_ErTHbrXsennZ8twV5b8xHFC1GtZb3xjm4M1Zs_j1vSGagiHxqp_0VtzMCcKtN31xjS9epk0wDPi4nI_SAkGlvt1XINQ3VNKvPKiA3RlvgDenfqYbize7eZRKFf4W1afODIe1WSXtgoyLa3hbwj_Qf1cqOlnsbRNJw1WVnGX-qdnw-q5MBTZMlgbWJGz65f4YlIW47zjuOHUmDQl3Z5gKFrUGYn6L2CrImnXimIctmbG08H1vcXO75DYnqTlfWaJfRmdXuEEQ64UuRaEG4NotZf9Nq5kq95KlURC344NxraUhyb_1XWc4jDMOmsycfk1H39I77FL-NCH_iiHZ4togZvRicEkgTX7BCwwLOZIpUHaxIOo4k1WKZpTeVI4jUPTm3iX8kPPtsAAAxZF1IhSnGaPvaYjOLO3S0hAPDQfus7nA2-eH-KAQSS19OoS2nYSXyssRYTkc"
}
Field | Type | Description |
---|---|---|
amount | integer | Prepaid Card value in cents (omit for closed loop) |
prepaid_card | (dict) | ⋯ |
⋯ card_subtype | string | Prepaid Card Subtype (open_loop or closed_loop ) |
⋯ bin | string | First 6 digits of PAN (optional) |
user_id | string | User ID (optional) |
user_authorization | string | Signed User Authorization Token, JWT-format (optional) |
Response Fields (Success)
✅ Response (OK)
200 OK
{
"payout_methods": [
{
"name": "PARTNER_ACH",
"display_name": "Direct Deposit",
"tag": "Most Popular",
"description": "Direct deposit to your account.",
"delivery_at": "2019-06-03T00:00:00Z",
"amount": 9350,
"fees": {
"base": 150,
"rate": 5000
}
},
{
"name": "PARTNER_INST",
"display_name": "Transfer to Debit Card",
"tag": "Fastest Delivery",
"description": "Transfer funds to your debit card.",
"delivery_at": "2019-06-01T00:00:00Z",
"amount": 9100,
"fees": {
"base": 200,
"rate": 7000
}
}
]
}
Field | Description |
---|---|
payout_methods | (array of dict) |
⋯ name | Name of payout method |
⋯ display_name | Name of payout method, for display |
⋯ tag | Auxiliary label of payout method |
⋯ description | Description of payout method |
⋯ delivery_at | Estimated delivery, ISO 8601 timestamp |
⋯ amount | Payout amount (integer cents, omitted for closed loop) |
⋯ fees | (dict) |
⋯ ⋯ base | Base (integer cents) |
⋯ ⋯ rate | Rate (integer percent * 1000) |
Response Fields (Errors)
❌ Response (validation error)
400 Bad Request
{
"errors": [
{
"code": "validation_error",
"title": "Validation Error",
"invalid_params": [
{
"name": "amount",
"reason": "cannot be empty"
}
]
}
]
}
❌ Response (limit exceeded)
422 Unprocessable Entity
{
"errors": [
{
"code": "daily_limit_exceeded",
"title": "Limit Exceeded",
"detail": "You have reached your daily limit of transactions."
}
]
}
Field | Description |
---|---|
errors | (array of dict) |
⋯ code | Error code |
⋯ title | Title of error, for display |
⋯ detail | Error message, for display |
Create Open Loop Transaction
This endpoint creates a new transaction.
Card data may be sent directly, or with an extra layer of encryption. Raw magnetic stripe data (MSD) can be sent in the encrypted_msd_track
fields.
User data can be included in this request using the user_authorization
field (see User Authorization Token). If the user has been created previously via Create User or an earlier transaction, send the user_id
field instead.
HTTP Request
POST https://api.prepaid2cash.com/v2/transactions
Request Body Fields
⏩ Request (Example 1: Direct card data, with optional fields)
POST /v2/transactions HTTP/1.1
Host: api.prepaid2cash.com
Content-Type: application/json
Authorization: pk_test_ImlkX2Zvcm0iOiJkcml
{
"amount": 10000,
"payout_method": "PARTNER_ACH",
"prepaid_card": {
"card_subtype": "open_loop",
"pan": "9123123412341234",
"expiry_month": "01",
"expiry_year": "2021",
"cvv": "123",
"pan_entry": "swipe"
},
"payout_card": {
"card_subtype": "debit",
"pan": "9123123412341234",
"expiry_month": "01",
"expiry_year": "2021",
"cvv": "123",
"pan_entry": "swipe"
},
"location": {
"id": "78205-00300",
"address": "300 Alamo Plaza, San Antonio, TX 78205, US",
"lat": "29.42569",
"long": "-98.48503",
},
"tos_accepted": true,
"verification_code": "12345",
"user_id": "e8379ab7-fe92-4ad0-b25e-6ba4ddb0999f",
"user_authorization": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilo2WkZTZXdENEZZYXlqOFNvV1JDX0VBcngxTSIsIng1dCI6Ilo2WkZTZXdENEZZYXlqOFNvV1JDX0VBcngxTSIsIng1dCNTMjU2Ijoickp2eXZOZGFEOEk1V293bmM3ZnhMMTlQS0NFREsxWGxyMHpYQndhMGxHUSJ9.eyJpc3MiOiJwYXJ0bmVyZG9tYWluLmNvbSIsImF1ZCI6InByZXBhaWQyY2FzaC5jb20iLCJpYXQiOjE1Nzc4MzY4MDAsImV4cCI6MjU3NzgzNjgwMCwiaHR0cDovL3AyYy5pby91c2VyIjp7ImlkIjoiZDU0NzQ3ZDEtMjk5My00YmRjLWE3NDUtMzIxZjdmMzNlOGFmIiwiZmlyc3RfbmFtZSI6Ikpvc2h1YSIsImxhc3RfbmFtZSI6Ik5vcnRvbiIsImFkZHJlc3MxIjoiNjI0IENvbW1lcmNpYWwgU3QiLCJhZGRyZXNzMiI6IiIsImNpdHkiOiJTYW4gRnJhbmNpc2NvIiwic3RhdGUiOiJDQSIsImNvdW50cnkiOiJVUyIsInBvc3RhbF9jb2RlIjoiOTQxMTEtMTAxMCIsInBob25lIjoiKzEgNDE1LTQ1Ni0xMDAwIiwiZW1haWwiOiJub3J0b25Ac2YuY2EudXMiLCJkb2IiOiIxOTc2LTAyLTA0Iiwic3NuX2xhc3RfNCI6IjE3NzYiLCJpZF9mb3JtIjoiZHJpdmVyc19saWNlbnNlIiwiaWRfaXNzdWVyIjoiVVMvQ0EiLCJpZF9udW1iZXIiOiJEMTIzNDU2NzgiLCJreWNfdmVyaWZpZWQiOlsiZmlyc3RfbmFtZSJdfX0.nbywUp4vkQ8uCphzpykrDm7jLHMl8Ixt9DJPIhWQQo7RYbIV6lmr4EwOWCg_TNcjf7l4jNhd33daD1qeCSNxpKMUs45joJlVKFPnjiu32PGNzfOdRw28ElWVCXzQOTR5_OLoRvx6xX_oIOQI9FuMlHyoNq9G6hBpM1zOey74GYunO6WNJPbDjh5bUpZB9L4z_OPs3SgzKzpOuTOLS7tBiiJsgHyS8pex4-_ErTHbrXsennZ8twV5b8xHFC1GtZb3xjm4M1Zs_j1vSGagiHxqp_0VtzMCcKtN31xjS9epk0wDPi4nI_SAkGlvt1XINQ3VNKvPKiA3RlvgDenfqYbize7eZRKFf4W1afODIe1WSXtgoyLa3hbwj_Qf1cqOlnsbRNJw1WVnGX-qdnw-q5MBTZMlgbWJGz65f4YlIW47zjuOHUmDQl3Z5gKFrUGYn6L2CrImnXimIctmbG08H1vcXO75DYnqTlfWaJfRmdXuEEQ64UuRaEG4NotZf9Nq5kq95KlURC344NxraUhyb_1XWc4jDMOmsycfk1H39I77FL-NCH_iiHZ4togZvRicEkgTX7BCwwLOZIpUHaxIOo4k1WKZpTeVI4jUPTm3iX8kPPtsAAAxZF1IhSnGaPvaYjOLO3S0hAPDQfus7nA2-eH-KAQSS19OoS2nYSXyssRYTkc"
}
⏩ Request (Example 2: Encrypted card data)
POST /v2/transactions HTTP/1.1
Host: api.prepaid2cash.com
Content-Type: application/json
Authorization: pk_test_ImlkX2Zvcm0iOiJkcml
{
"amount": 10000,
"payout_method": "PARTNER_ACH",
"prepaid_card": {
"card_subtype": "open_loop",
"encryption_alg": "3DES-112-DUKPT",
"encryption_ksn": "FFFF9876543210E00008",
"encrypted_card": "C25C1D1197D31CAA87285D59A5ABE72",
"encrypted_msd_track1": "C25C1D1197D31CAA87285D59A892047426D918…",
"encrypted_msd_track2": "C25C1D1197D31CAA87285D59A892047426D918…",
"pan_entry": "swipe"
},
"payout_card": {
"card_subtype": "debit",
"encryption_alg": "3DES-112-DUKPT",
"encryption_ksn": "FFFF9876543210E00008",
"encrypted_card": "C25C1D1197D31CAA87285D59A5ABE72",
"encrypted_msd_track1": "C25C1D1197D31CAA87285D59A892047426D918…",
"encrypted_msd_track2": "C25C1D1197D31CAA87285D59A892047426D918…",
"pan_entry": "swipe"
},
"location": {
"id": "78205-00300",
"address": "300 Alamo Plaza, San Antonio, TX 78205, US",
"lat": "29.42569",
"long": "-98.48503",
},
"tos_accepted": true,
"verification_code": "12345",
"user_id": "e8379ab7-fe92-4ad0-b25e-6ba4ddb0999f",
"user_authorization": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilo2WkZTZXdENEZZYXlqOFNvV1JDX0VBcngxTSIsIng1dCI6Ilo2WkZTZXdENEZZYXlqOFNvV1JDX0VBcngxTSIsIng1dCNTMjU2Ijoickp2eXZOZGFEOEk1V293bmM3ZnhMMTlQS0NFREsxWGxyMHpYQndhMGxHUSJ9.eyJpc3MiOiJwYXJ0bmVyZG9tYWluLmNvbSIsImF1ZCI6InByZXBhaWQyY2FzaC5jb20iLCJpYXQiOjE1Nzc4MzY4MDAsImV4cCI6MjU3NzgzNjgwMCwiaHR0cDovL3AyYy5pby91c2VyIjp7ImlkIjoiZDU0NzQ3ZDEtMjk5My00YmRjLWE3NDUtMzIxZjdmMzNlOGFmIiwiZmlyc3RfbmFtZSI6Ikpvc2h1YSIsImxhc3RfbmFtZSI6Ik5vcnRvbiIsImFkZHJlc3MxIjoiNjI0IENvbW1lcmNpYWwgU3QiLCJhZGRyZXNzMiI6IiIsImNpdHkiOiJTYW4gRnJhbmNpc2NvIiwic3RhdGUiOiJDQSIsImNvdW50cnkiOiJVUyIsInBvc3RhbF9jb2RlIjoiOTQxMTEtMTAxMCIsInBob25lIjoiKzEgNDE1LTQ1Ni0xMDAwIiwiZW1haWwiOiJub3J0b25Ac2YuY2EudXMiLCJkb2IiOiIxOTc2LTAyLTA0Iiwic3NuX2xhc3RfNCI6IjE3NzYiLCJpZF9mb3JtIjoiZHJpdmVyc19saWNlbnNlIiwiaWRfaXNzdWVyIjoiVVMvQ0EiLCJpZF9udW1iZXIiOiJEMTIzNDU2NzgiLCJreWNfdmVyaWZpZWQiOlsiZmlyc3RfbmFtZSJdfX0.nbywUp4vkQ8uCphzpykrDm7jLHMl8Ixt9DJPIhWQQo7RYbIV6lmr4EwOWCg_TNcjf7l4jNhd33daD1qeCSNxpKMUs45joJlVKFPnjiu32PGNzfOdRw28ElWVCXzQOTR5_OLoRvx6xX_oIOQI9FuMlHyoNq9G6hBpM1zOey74GYunO6WNJPbDjh5bUpZB9L4z_OPs3SgzKzpOuTOLS7tBiiJsgHyS8pex4-_ErTHbrXsennZ8twV5b8xHFC1GtZb3xjm4M1Zs_j1vSGagiHxqp_0VtzMCcKtN31xjS9epk0wDPi4nI_SAkGlvt1XINQ3VNKvPKiA3RlvgDenfqYbize7eZRKFf4W1afODIe1WSXtgoyLa3hbwj_Qf1cqOlnsbRNJw1WVnGX-qdnw-q5MBTZMlgbWJGz65f4YlIW47zjuOHUmDQl3Z5gKFrUGYn6L2CrImnXimIctmbG08H1vcXO75DYnqTlfWaJfRmdXuEEQ64UuRaEG4NotZf9Nq5kq95KlURC344NxraUhyb_1XWc4jDMOmsycfk1H39I77FL-NCH_iiHZ4togZvRicEkgTX7BCwwLOZIpUHaxIOo4k1WKZpTeVI4jUPTm3iX8kPPtsAAAxZF1IhSnGaPvaYjOLO3S0hAPDQfus7nA2-eH-KAQSS19OoS2nYSXyssRYTkc"
}
Field | Type | Description |
---|---|---|
amount | integer | Prepaid Card value in cents |
payout_method | string | Selected from transaction_options response |
prepaid_card | (dict) | ⋯ |
⋯ card_subtype | string | Prepaid Card subtype (open_loop ) |
⋯ (card data) | ⋯ | (see below) |
⋯ pan_entry | string | PAN entry method (scan , swipe , or manual ) |
payout_card | (dict) | ⋯ (optional) |
⋯ (card data) | ⋯ | (see below) |
⋯ pan_entry | string | PAN entry method (scan , swipe , or manual ) |
location | (dict) | ⋯ |
⋯ id | string | Identifier for physical customer location, unique within Partner domain |
⋯ address | string | Location address |
⋯ lat | string | Location coordinates, latitude (decimal) |
⋯ long | string | Location coordinates, longitude (decimal) |
tos_accepted | boolean | Indicates that user has accepted Prepaid2Cash Terms of Service |
verification_code | string | SMS verification code sent to user's mobile phone |
user_id | string | User ID from Create User (optional, see notes above) |
user_authorization | string | Signed User Authorization Token, JWT-format (optional, see notes above) |
Card Data Fields (Example 1: Direct card data)
Field | Type | Description |
---|---|---|
⋯ pan | string | Full card PAN |
⋯ expiry_month | string | 2-digit, zero-padded, numeric month |
⋯ expiry_year | string | 4-digit year |
⋯ cvv | string | Card Security Code |
Card Data Fields (Example 2: Encrypted card data)
Field | Type | Description |
---|---|---|
⋯ encryption_alg | string | Encryption Algorithm (3DES-112-DUKPT or by Partner Agreement) |
⋯ encryption_kid | string | Encryption Key ID (if applicable) |
⋯ encryption_ksn | string | Encryption Key Serial Number (if applicable) |
⋯ encrypted_msd_track1 | string | Magnetic Stripe Data Track 1, encrypted, raw (optional) |
⋯ encrypted_msd_track2 | string | Magnetic Stripe Data Track 2, encrypted, raw (optional) |
Response Fields
✅ Response (OK)
201 Created
{
"transaction_results": "eyJhbGciOiJIUzI1NiIsInR5cCI6I…"
}
❌ Response (validation error)
400 Bad Request
{
"errors": [
{
"code": "validation_error",
"title": "Validation Error",
"invalid_params": [
{
"name": "first_name",
"reason": "cannot be empty"
}
]
}
]
}
Field | Description |
---|---|
transaction_results | Signed Transaction Results Token, JWT-format |
Retrieve Closed Loop Merchants
This endpoint returns the active list of gift card merchants which are being purchased. Typical length is 80-120 merchants.
HTTP Request
GET https://api.prepaid2cash.com/v2/closed_loop_card_lines
⏩ Request
GET /v2/closed_loop_card_lines HTTP/1.1
Host: api.prepaid2cash.com
Authorization: pk_test_ImlkX2Zvcm0iOiJkcml
Response Fields
✅ Response
200 OK
[
{
"card_line_id": 3,
"merchant_name": "AMC Theatres",
"discount_rate": 0.49,
"logo_url": "https://logo.png"
},
{
"card_line_id": 4,
"merchant_name": "American Airlines",
"discount_rate": 0.37,
"logo_url": "https://logo.png"
},
...
]
Field | Description |
---|---|
(array of dict) | |
⋯ card_line_id | ID of merchant card line |
⋯ merchant_name | Name of Merchant, for display |
⋯ discount_rate | Estimated card purchase discount rate |
⋯ logo_url | Merchant logo URL |
Create Closed Loop Transaction
This endpoint requests an offer to purchase a Closed Loop card.
It is not necessary to submit a card value -- this will be obtained from the merchant.
HTTP Request
POST https://api.prepaid2cash.com/v2/transactions
Request Body Fields
⏩ Request
POST /v2/transactions HTTP/1.1
Host: api.prepaid2cash.com
Content-Type: application/json
Authorization: pk_test_ImlkX2Zvcm0iOiJkcml
{
"payout_method": "PARTNER_ACH",
"prepaid_card": {
"card_subtype": "closed_loop",
"card_line_id": 9,
"pan": "9111111111111102",
"pin": "2600",
"pan_entry": "scan"
},
"tos_accepted": true,
"user_authorization": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilo2WkZTZXdENEZZYXlqOFNvV1JDX0VBcngxTSIsIng1dCI6Ilo2WkZTZXdENEZZYXlqOFNvV1JDX0VBcngxTSIsIng1dCNTMjU2Ijoickp2eXZOZGFEOEk1V293bmM3ZnhMMTlQS0NFREsxWGxyMHpYQndhMGxHUSJ9.eyJpc3MiOiJwYXJ0bmVyZG9tYWluLmNvbSIsImF1ZCI6InByZXBhaWQyY2FzaC5jb20iLCJpYXQiOjE1Nzc4MzY4MDAsImV4cCI6MjU3NzgzNjgwMCwiaHR0cDovL3AyYy5pby91c2VyIjp7ImlkIjoiZDU0NzQ3ZDEtMjk5My00YmRjLWE3NDUtMzIxZjdmMzNlOGFmIiwiZmlyc3RfbmFtZSI6Ikpvc2h1YSIsImxhc3RfbmFtZSI6Ik5vcnRvbiIsImFkZHJlc3MxIjoiNjI0IENvbW1lcmNpYWwgU3QiLCJhZGRyZXNzMiI6IiIsImNpdHkiOiJTYW4gRnJhbmNpc2NvIiwic3RhdGUiOiJDQSIsImNvdW50cnkiOiJVUyIsInBvc3RhbF9jb2RlIjoiOTQxMTEtMTAxMCIsInBob25lIjoiKzEgNDE1LTQ1Ni0xMDAwIiwiZW1haWwiOiJub3J0b25Ac2YuY2EudXMiLCJkb2IiOiIxOTc2LTAyLTA0Iiwic3NuX2xhc3RfNCI6IjE3NzYiLCJpZF9mb3JtIjoiZHJpdmVyc19saWNlbnNlIiwiaWRfaXNzdWVyIjoiVVMvQ0EiLCJpZF9udW1iZXIiOiJEMTIzNDU2NzgiLCJreWNfdmVyaWZpZWQiOlsiZmlyc3RfbmFtZSJdfX0.nbywUp4vkQ8uCphzpykrDm7jLHMl8Ixt9DJPIhWQQo7RYbIV6lmr4EwOWCg_TNcjf7l4jNhd33daD1qeCSNxpKMUs45joJlVKFPnjiu32PGNzfOdRw28ElWVCXzQOTR5_OLoRvx6xX_oIOQI9FuMlHyoNq9G6hBpM1zOey74GYunO6WNJPbDjh5bUpZB9L4z_OPs3SgzKzpOuTOLS7tBiiJsgHyS8pex4-_ErTHbrXsennZ8twV5b8xHFC1GtZb3xjm4M1Zs_j1vSGagiHxqp_0VtzMCcKtN31xjS9epk0wDPi4nI_SAkGlvt1XINQ3VNKvPKiA3RlvgDenfqYbize7eZRKFf4W1afODIe1WSXtgoyLa3hbwj_Qf1cqOlnsbRNJw1WVnGX-qdnw-q5MBTZMlgbWJGz65f4YlIW47zjuOHUmDQl3Z5gKFrUGYn6L2CrImnXimIctmbG08H1vcXO75DYnqTlfWaJfRmdXuEEQ64UuRaEG4NotZf9Nq5kq95KlURC344NxraUhyb_1XWc4jDMOmsycfk1H39I77FL-NCH_iiHZ4togZvRicEkgTX7BCwwLOZIpUHaxIOo4k1WKZpTeVI4jUPTm3iX8kPPtsAAAxZF1IhSnGaPvaYjOLO3S0hAPDQfus7nA2-eH-KAQSS19OoS2nYSXyssRYTkc"
}
Field | Type | Description |
---|---|---|
payout_method | string | Selected from transaction_options response |
prepaid_card | (dict) | ⋯ |
⋯ card_subtype | string | Prepaid Card subtype (closed_loop ) |
⋯ card_line_id | integer | (from Retrieve Closed Loop Merchants) |
⋯ pan | string | Full card PAN |
⋯ pin | string | Card PIN (if present) |
⋯ pan_entry | string | PAN entry method (scan , swipe , or manual ) |
tos_accepted | boolean | Indicates that user has accepted Prepaid2Cash Terms of Service |
user_authorization | string | Signed User Authorization Token, JWT-format |
Response
✅ Response (OK)
201 Created
{
"transaction": {
"id": "0479d573-2c4a-4a43-a717-3d2e1cea11e4",
"payout_amount": 9900
}
}
❌ Response (validation error)
400 Bad Request
{
"errors": [
{
"code": "validation_error",
"title": "Validation Error",
"invalid_params": [
{
"name": "first_name",
"reason": "cannot be empty"
}
]
}
]
}
❌ Response (declined)
422 Unprocessable Entity
{
"errors": [
{
"code": "card_not_valid_for_merchant",
"title": "Transaction Declined",
"detail": "Card number or PIN incorrect"
}
]
}
Field | Description |
---|---|
transaction | (dict) |
⋯ id | Transaction ID |
⋯ payout_amount | Amount user will receive, if offer is accepted |
Accept Closed Loop Offer
This endpoint accepts an offer to purchase a Closed Loop card.
HTTP Request
POST https://api.prepaid2cash.com/v2/transactions/{id}/accept_offer
Request Body Fields
⏩ Request
POST /v2/transactions/{id}/accept_offer HTTP/1.1
Host: api.prepaid2cash.com
Content-Type: application/json
Authorization: pk_test_ImlkX2Zvcm0iOiJkcml
(none)
Response
✅ Response (OK)
200 OK
{
"transaction_results": "eyJhbGciOiJIUzI1NiIsInR5cCI6I…"
}
Field | Description |
---|---|
transaction_results | Signed Transaction Results Token, JWT-format |
Decline Closed Loop Offer
This endpoint declines an offer to purchase a Closed Loop card.
HTTP Request
POST https://api.prepaid2cash.com/v2/transactions/{id}/decline_offer
Request Body Fields
⏩ Request
POST /v2/transactions/{id}/decline_offer HTTP/1.1
Host: api.prepaid2cash.com
Content-Type: application/json
Authorization: pk_test_ImlkX2Zvcm0iOiJkcml
(none)
Response Fields
✅ Response (OK)
204 No Content
(none)
Tokens
The Prepaid2Cash Partner API requires the exchange of trusted and verified data, such as user information and transaction results. To ensure the integrity of this data, while allowing it to be sent through potentially-insecure channels, all trusted data is cryptographically signed by the creator, and verified by the consumer.
We use the JSON Web Token (JWT) specification as a serialization format. See JWT.io and RFC7519 for details.
Tokens are cryptographically signed using the algorithm specified in Partner Agreement:
HS256
HMAC-SHA256 (symmetric, secret key must be securely pre-shared)
🔵 Production JWKS Endpoint
https://api.prepaid2cash.com/.well-known/jwks.json
🔵 Sandbox JWKS Endpoint
https://sandbox.api.prepaid2cash.com/.well-known/jwks.json
RS256
RSASSA-PKCS1-v1_5-SHA256 (asymmetric, public keys can be pre-exchanged or retrieved from well-known JWKS endpoints. Requires additional fields in JWT header:kid
,x5t
,x5t#S256
)
The Prepaid2Cash Partner API uses two kinds of signed tokens:
- User Authorization Tokens (UAT), generated by Partner API and trusted by Prepaid2Cash for delivery of required user information
- Transaction Results Tokens (TRT), generated by Prepaid2Cash API and returned to Partner for followup transaction processing
User Authorization Tokens
⏩ Sample UAT Request
GET /v2/sample_uat HTTP/1.1
Host: sandbox.api.prepaid2cash.com
Authorization: pk_test_ImlkX2Zvcm0iOiJkcml
UATs are generated by Partner (typically by a backend API server) and sent to Prepaid2Cash. They may be delivered directly or via Partner or third-party clients, such as mobile apps.
Prepaid2Cash will verify the signature of all UATs received.
A signed and verified UAT indicates:
- User is known and authenticated to the Partner
- Partner authorizes user to create transactions via the Prepaid2Cash API
- Partner will receive transaction results from Prepaid2Cash, and will process them on behalf of the user
UATs may include several fields of user data in the JWT Payload. Required fields will vary by Partner Agreement.
JWT Contents
🔵 User Authorization Token Sample, JSON source
{
"typ": "JWT",
"alg": "RS256",
"kid": "Z6ZFSewD4FYayj8SoWRC_EArx1M",
"x5t": "Z6ZFSewD4FYayj8SoWRC_EArx1M",
"x5t#S256": "rJvyvNdaD8I5Wownc7fxL19PKCEDK1Xlr0zXBwa0lGQ"
}
{
"iss": "partnerdomain.com",
"aud": "prepaid2cash.com",
"iat": 1577836800,
"exp": 2577836800,
"http://p2c.io/user": {
"id": "d54747d1-2993-4bdc-a745-321f7f33e8af",
"first_name": "Joshua",
"last_name": "Norton",
"address1": "624 Commercial St",
"address2": "",
"city": "San Francisco",
"state": "CA",
"country": "US",
"postal_code": "94111",
"phone": "+14154561000",
"email": "norton@sf.ca.us",
"dob": "1976-02-04",
"ssn_last_4": "1776",
"id_form": "drivers_license",
"id_issuer": "US/CA",
"id_number": "D12345678",
"kyc_verified": [
"first_name"
]
}
}
🔵 User Authorization Token Sample, encoded and signed
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilo2WkZTZXdENEZZYXlqOFNvV1JDX0VBcngxTSIsIng1dCI6Ilo2WkZTZXdENEZZYXlqOFNvV1JDX0VBcngxTSIsIng1dCNTMjU2Ijoickp2eXZOZGFEOEk1V293bmM3ZnhMMTlQS0NFREsxWGxyMHpYQndhMGxHUSJ9.eyJpc3MiOiJwYXJ0bmVyZG9tYWluLmNvbSIsImF1ZCI6InByZXBhaWQyY2FzaC5jb20iLCJpYXQiOjE1Nzc4MzY4MDAsImV4cCI6MjU3NzgzNjgwMCwiaHR0cDovL3AyYy5pby91c2VyIjp7ImlkIjoiZDU0NzQ3ZDEtMjk5My00YmRjLWE3NDUtMzIxZjdmMzNlOGFmIiwiZmlyc3RfbmFtZSI6Ikpvc2h1YSIsImxhc3RfbmFtZSI6Ik5vcnRvbiIsImFkZHJlc3MxIjoiNjI0IENvbW1lcmNpYWwgU3QiLCJhZGRyZXNzMiI6IiIsImNpdHkiOiJTYW4gRnJhbmNpc2NvIiwic3RhdGUiOiJDQSIsImNvdW50cnkiOiJVUyIsInBvc3RhbF9jb2RlIjoiOTQxMTEtMTAxMCIsInBob25lIjoiKzEgNDE1LTQ1Ni0xMDAwIiwiZW1haWwiOiJub3J0b25Ac2YuY2EudXMiLCJkb2IiOiIxOTc2LTAyLTA0Iiwic3NuX2xhc3RfNCI6IjE3NzYiLCJpZF9mb3JtIjoiZHJpdmVyc19saWNlbnNlIiwiaWRfaXNzdWVyIjoiVVMvQ0EiLCJpZF9udW1iZXIiOiJEMTIzNDU2NzgiLCJreWNfdmVyaWZpZWQiOlsiZmlyc3RfbmFtZSJdfX0.nbywUp4vkQ8uCphzpykrDm7jLHMl8Ixt9DJPIhWQQo7RYbIV6lmr4EwOWCg_TNcjf7l4jNhd33daD1qeCSNxpKMUs45joJlVKFPnjiu32PGNzfOdRw28ElWVCXzQOTR5_OLoRvx6xX_oIOQI9FuMlHyoNq9G6hBpM1zOey74GYunO6WNJPbDjh5bUpZB9L4z_OPs3SgzKzpOuTOLS7tBiiJsgHyS8pex4-_ErTHbrXsennZ8twV5b8xHFC1GtZb3xjm4M1Zs_j1vSGagiHxqp_0VtzMCcKtN31xjS9epk0wDPi4nI_SAkGlvt1XINQ3VNKvPKiA3RlvgDenfqYbize7eZRKFf4W1afODIe1WSXtgoyLa3hbwj_Qf1cqOlnsbRNJw1WVnGX-qdnw-q5MBTZMlgbWJGz65f4YlIW47zjuOHUmDQl3Z5gKFrUGYn6L2CrImnXimIctmbG08H1vcXO75DYnqTlfWaJfRmdXuEEQ64UuRaEG4NotZf9Nq5kq95KlURC344NxraUhyb_1XWc4jDMOmsycfk1H39I77FL-NCH_iiHZ4togZvRicEkgTX7BCwwLOZIpUHaxIOo4k1WKZpTeVI4jUPTm3iX8kPPtsAAAxZF1IhSnGaPvaYjOLO3S0hAPDQfus7nA2-eH-KAQSS19OoS2nYSXyssRYTkc
Header Fields
Field | Type | Description |
---|---|---|
typ | string | Token type (always JWT ) |
alg | string | Signature algorithm (HS256 , RS256 ) |
kid | string | ID of signing key (when alg: RS256 ) |
x5t | string | SHA1 thumbprint of signing key (when alg: RS256 ) |
x5t#S256 | string | SHA256 thumbprint of signing key (when alg: RS256 ) |
Payload Fields
Field | Type | Description |
---|---|---|
iss | string | Token issuer identifier (Partner primary domain name) |
aud | string | Token audience identifier (always prepaid2cash.com ) |
iat | integer | Token creation time, in UNIX time format (seconds since epoch) |
exp | integer | Token expiration, in UNIX time format (seconds since epoch) |
http://p2c.io/user | (dict) | ⋯ |
⋯ id | string | User ID, unique in Partner domain |
⋯ first_name | string | |
⋯ last_name | string | |
⋯ address1 | string | |
⋯ address2 | string | |
⋯ city | string | |
⋯ state | string | State, USPS 2-letter format (CA , AL , etc) |
⋯ country | string | Country code, ISO 3166-1 alpha-2 format (always US ) |
⋯ postal_code | string | USPS ZIP or ZIP+4 postal code |
⋯ phone | string | Telephone number with country code, ITU-T E.123 format, hyphens optional |
⋯ email | string | Email address |
⋯ dob | string | Date of Birth, ISO 8601 datestamp |
⋯ ssn_last_4 | string | Last 4 digits of SSN |
⋯ id_form | string | Government-Issued ID form |
⋯ id_issuer | string | Government-Issued ID issuer |
⋯ id_number | string | Government-Issued ID number |
⋯ kyc_verified | array of string | List of fields KYC-verified by Partner |
Transaction Results Tokens
TRTs are generated by Prepaid2Cash, and sent to Partner. They may be delivered directly or via Partner or third-party clients, such as mobile apps.
A signed and verified TRT indicates:
- Transaction was submitted to Prepaid2Cash by User
- Prepaid2Cash has attempted to process transaction and has obtained the included results
- If successful, Prepaid2Cash has captured specified funds from card, and authorizes payout via Partner, if applicable
TRTs will include several fields of transaction data in the JWT Payload.
JWT Contents
🔵 Transaction Results Token Sample, encoded and signed
eyJhbGciOiJSUzI1NiIsImtpZCI6Ilo2WkZTZXdENEZZYXlqOFNvV1JDX0VBcngxTSIsInR5cCI6IkpXVCIsIng1dCI6Ilo2WkZTZXdENEZZYXlqOFNvV1JDX0VBcngxTSIsIng1dCNTMjU2Ijoickp2eXZOZGFEOEk1V293bmM3ZnhMMTlQS0NFREsxWGxyMHpYQndhMGxHUSJ9.eyJpc3MiOiJwcmVwYWlkMmNhc2guY29tIiwiYXVkIjoiYmF5YmFuay5leGFtcGxlLmNvbSIsImlhdCI6MTU3OTIxMzIzMSwiZXhwIjoxNTc5MjE0MTMxLCJodHRwOi8vcDJjLmlvL3RyYW5zYWN0aW9uIjp7ImlkIjoiYzk2NWRhMDkyZCIsInVzZXJfaWQiOiJkNTQ3NDdkMS0yOTkzLTRiZGMtYTc0NS0zMjFmN2YzM2U4YWYiLCJjYXJkX3N1YnR5cGUiOiJvcGVuX2xvb3AiLCJtYXNrZWRfcGFuIjoiNDExMTExKioqKioqMzM0NyIsImV4cGlyYXRpb24iOiIwNy8yMDIyIiwiYW1vdW50IjoxMDAwMCwicGF5b3V0X2Ftb3VudCI6OTQwMCwicGF5b3V0X21ldGhvZCI6IkJBWUJBTktfQUNIIiwiY2FwdHVyZWRfYXQiOiIyMDIwLTAxLTE2VDIyOjIwOjMxWiIsImRlbGl2ZXJ5X2F0IjoiMjAyMC0wMS0xN1QxNzowMDowMFoifX0.XEkoW2pG3mZnLts0Gb6sPExtMJDcsgbB8c-AV6R4YXXJfmmtscFtUW97buPH9s5r_1uFwtBfqXJAXLRYQ2-6hHiqdPXmmOQ1csaU9NXU03lTPqAaZUqVab7W7aKNqTkvSvqwRwx-KjARYXJ1pE6-P9txPz8r9dGeKmC-N4YM6yQFpe0Eo6aE_8JyU87iu1yMuu8fyYozU_GddcrRVNbB4p78hHmxMyYtMVbbJGgROAnIlAJBean8tMnt5crE_5CxxX2fkyl3HcK1oQJVewkoBQR3YmiftClftDYsvjaJTTwp7gOlDBuKcgYl7rIS7lPUQOiCqMSJSoS3MS2-bK3zX2qrwsySNv7Z4zu0jX2_05kEWyI8mm31XJfP1X55woUiegv2NcGk_MhrGle34GaHK2g0CX2_084FuhAPiROwQWEP_UVqo5qgAaTrbf2_vVkhtXgOWbg_hwLmM0Qn42NX3yrE5DSwtPSXaoXTi_-XljLDPttmI8m5En95ZaSImuEhayGpMfOj1bivuU1xDkjF801LcJguBTt_L9nxRaqPm4g0kxXtI13oGMSgUL3-9g8FFXAb_4-rfcbzJyG-TC5NnhvdD1t4_8DpiMZ-FVGoJSF2U8wLK54vIQZhYScuWguKMMxt0ZcHrAHo9RnYRYOtNPjLL3Flh2zdqNu1nnkbeGg
🔵 Transaction Results Token Sample, decoded and verified
{
"alg": "RS256",
"kid": "Z6ZFSewD4FYayj8SoWRC_EArx1M",
"typ": "JWT",
"x5t": "Z6ZFSewD4FYayj8SoWRC_EArx1M",
"x5t#S256": "rJvyvNdaD8I5Wownc7fxL19PKCEDK1Xlr0zXBwa0lGQ"
}
{
"iss": "prepaid2cash.com",
"aud": "partnerdomain.com",
"iat": 1579213231,
"exp": 1579214131,
"http://p2c.io/transaction": {
"id": "c965da092d",
"user_id": "d54747d1-2993-4bdc-a745-321f7f33e8af",
"card_subtype": "open_loop",
"masked_pan": "411111******3347",
"expiration": "07/2022",
"amount": 10000,
"payout_amount": 9400,
"payout_method": "PARTNER_ACH",
"captured_at": "2020-01-16T22:20:31Z",
"delivery_at": "2020-01-17T17:00:00Z"
}
}
Header Fields
Field | Type | Description |
---|---|---|
typ | string | Token type (always JWT ) |
alg | string | Signature algorithm (HS256 , RS256 ) |
kid | string | ID of signing key (when alg: RS256 ) |
x5t | string | SHA1 thumbprint of signing key (when alg: RS256 ) |
x5t#S256 | string | SHA256 thumbprint of signing key (when alg: RS256 ) |
Payload Fields
Field | Type | Description |
---|---|---|
iss | string | Token issuer identifier (always prepaid2cash.com ) |
aud | string | Token audience identifier (Partner primary domain name) |
iat | integer | Token creation time, in UNIX time format (seconds since epoch) |
exp | integer | Token expiration, in UNIX time format (seconds since epoch) |
http://p2c.io/transaction | (dict) | ⋯ |
⋯ id | string | Unique transaction ID |
⋯ user_id | string | User ID from UAT |
⋯ card_subtype | string | open_loop or closed_loop |
⋯ masked_pan | string | Card PAN, masked for privacy |
⋯ expiration | string | Card expiration |
⋯ amount | integer | Transaction amount (cents) |
⋯ payout_amount | integer | Payout amount (cents) |
⋯ payout_method | string | Payout method from transaction_options |
⋯ captured_at | string | Capture time, ISO 8601 timestamp |
⋯ delivery_at | string | Estimated delivery time, ISO 8601 timestamp |
Testing
You can use the following test data to elicit different responses from the Sandbox environment:
Open Loop Test Data
Field and value | Result |
---|---|
amount < 2000 |
Error: Amount out of range |
amount = 49001 |
Error: Card capture failed |
amount = 49101 |
Error: User transaction limits exceeded |
amount > 49800 |
Error: Transaction declined |
amount > 50000 |
Error: Amount out of range |
Closed Loop Test Data
Field and value | Result |
---|---|
pin = 49001 |
Error: Card capture failed |
pin = 49101 |
Error: User transaction limits exceeded |
pin > 49800 |
Error: Transaction declined |
HTTP Response Codes
The Prepaid2Cash Partner API may return the following HTTP error response codes:
Code | Meaning |
---|---|
400 | Bad Request Your request was badly-formed, or failed validation. Inspect the response object for details. |
401 | Unauthorized Your API key is missing or invalid. |
403 | Forbidden Your Partner account does not have permission to modify this resource. |
404 | Not Found You have requested an unknown resource. |
405 | Method Not Allowed You have requested a resource using an invalid method. |
406 | Not Acceptable You have requested an invalid resource format. |
422 | Unprocessable Entity Your request ran afoul of application processing. Inspect the response object for details. |
429 | Too Many Requests You have exceeded request rate limits. |
500 | Internal Server Error We encountered an error while processing your request. This is a bug! |
503 | Service Unavailable We are temporarily offline for maintenance. Please try again later. |