Search Overlay

Venmo Integration - iOS

Prerequisites

API key

For information about how to get your API key from the Business Portal, see Before you begin.

Using the Demo app

In order to test the Venmo integration using the Demo app, you have to modify some constants representing the API key and the account id associated with the Venmo payment method.

  • Open Example/LotteryTicket/LotteryTicket/Managers/PaymentManager.swift file. 

  • Modify apiKey string to contain your API key
  • Modify venmoAccountId string to contain the account id associated with the Venmo payment method. 

Testing on mTest environment

To test the Venmo integration on iOS mTest environment, you have to setup the SDK with the .test parameter. 

Also, keep in mind that testing in mTest environment requires the Venmo Test app, and not the production one (the one from AppStore). Otherwise, the authorization will fail. The Venmo test app doesn't require any credentials - any email and any password will work.

The iOS test app is available through PayPal's AppCenter and you need to reach out to integrations@paysafe.com for access. 

Integrating the iOS SDK

Swift Package Manager 

In Xcode, select File > Add Packages… and enter https://github.com/paysafegroup/paysafe_sdk_ios_payments_api as the repository URL and select the latest version number.

Tick the checkboxes for the specific Paysafe libraries you wish to include. In this case, PaysafeVenmo.

If you look at your app target, you will see that the Paysafe libraries you chose are automatically linked as a frameworks to your app (see General > Frameworks, Libraries, and Embedded Content). 

// In your Swift file
import PaysafeVenmo

Cocoapods

// Add in your Podfile

pod 'PaysafePaymentsSDK'

 

// Or you can import only a single module

pod 'PaysafePaymentsSDK/PaysafeVenmo'

// In your Swift file
import PaysafePaymentsSDK

You can check the Github releases to see what is the latest version: https://github.com/paysafegroup/paysafe_sdk_ios_payments_api

Setup

After Paysafe iOS package is integrated into your project, setup PaysafeSDK on application start.

import PaysafeVenmo
PaysafeSDK.shared.setup(  
apiKey: apiKey,   
environment: .test
)
{ result in
    switch result {
    case .success:
        print("[Paysafe SDK] initialized successfully")
    case let .failure(error):
        print("[Paysafe SDK] initialize failure \(error.displayMessage)")
    }
}

The setup function creates and initializes the Paysafe iOS SDK. Pass the following parameters during its initialization from the application:

Parameter Required Type Description
apiKey true String The Base64-encoded version of the single-use token API key is used to authenticate with the Payment Hub REST API.
environment true PaysafeEnvironment PaysafeEnvironment is an enum type with the following cases:
  • production
  • test
theme false PSTheme This parameter is specific for Card Payments.

If theme parameter is not provided, then the default theme is applied.

API Key

The Base64-encoded version of the single-use token API key is used to authenticate with the Payment Hub REST API. Please refer “Before You Being” on how to obtain the API Keys

Note that this key can be used only to generate single-use tokens for use with the Payments API and has no other API access rights (such as for taking payments). Consequently, it can be exposed publicly in the user's browser.

 

Environment

The environment string is used to select the environment to use for tokenization. The accepted environments are LIVE (the Paysafe Production environment) and TEST (the Paysafe Merchant Test or Sandbox environment).

Do not use real card numbers or other payment instrument details in the Merchant Test environment. It is not compliant with Payment Card Industry Data Security Standards (PCI-DSS) and does not protect cardholder/payee information. Any upload of real cardholder data is strictly prohibited, as described in the Terms of Use.

 

Callback error object

The following table describes the contents of the error object:

Parameter Required Type Description
code true String Error code

displayMessage

true

String

Error message for display to customers.

detailedMessage

true

String

Detailed description of the error (this information should not be displayed to customers).

correlationId

true

String

Unique error ID to be provided to Paysafe Support during investigation

 

Setup errors

Error code Display message Detailed message Comments

9167

There was an error (9167), please contact our support.

The API key should not be empty.

 

9013

There was an error (9013), please contact our support.

Invalid API key.

The decoded API key does not conform with the format "username:password".

 

Setup your app for context switching

To include Venmo module in your App, it is necessary to include add some configuration in your app.

The following steps will enable your App to open the Venmo app, and Venmo app to redirect to your App.

Register a URL type

  1. In Xcode, click on your project in the Project Navigator and navigate to App Target > InfoURL Types
  2. Click [+] to add a new URL type
  3. Under URL Schemes, enter your app switch return URL scheme. This scheme must start with your app's Bundle ID and be dedicated to Braintree app switch returns.
    • For example, if the app bundle ID is com.your-company.your-app, then your URL scheme could be com.your-company.your-app.payments.

Set your return URL

To set the return URL call the setURLScheme in willConnectTo method in the UISceneDelegate.

For example, if the app bundle ID is com.your-company.your-app, then your URL scheme could be com.your-company.your-app.payments.

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {       
    PSVenmoContext.setURLScheme(scheme: "com.your-company.your-app.payments")
}

Set your URL Contexts

To set the url contexts call the openURLContexts in openURLContexts method in the UISceneDelegate

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        PSVenmoContext.setURLContexts(contexts: URLContexts)
}

Location Permissions

The Paysafe iOS SDK uses device and browser location data for fraud detection, Apple requires a NSLocationWhenInUseUsageDescription key in your Info.plist if your app contains code referencing location APIs.

Even If your app does not request location data directly, you will still need to include a NSLocationWhenInUseUsageDescriptionplist entry.

<key>NSLocationWhenInUseUsageDescription</key>
<string>Your location is required for our App</string>

Allowlist Venmo URL scheme

You must add the following to the query schemes allowlist in your app's info.plist:

<key>LSApplicationQueriesSchemes</key>
<array>
  <string>com.venmo.touch.v2</string>
</array>

Initialize

When you want to process a Venmo payment request, you would first initialize PSVenmoContext.

The initialize() method signature is the following:

/// Initializes the PSVenmoContext.
///
/// - Parameters:
///   - currencyCode: Currency code
///   - accountId: Account id
///   - completion: PSVenmoContextInitializeBlock
public static func initialize(
        currencyCode: String,
        accountId: String,
        completion: @escaping PSVenmoContextInitializeBlock
    )

Parameter Required Type Description

currencyCode

true

String

The currencyCode accepts 3 letter abbreviations of the ISO standard currencies.

accountId

true

String

The id of the selected merchant account to use to process the payment.

If you are a merchant, then this field is required only if you have more than one account configured for the same payment method and currency. If you are a partner using a shared API key, then this field is mandatory.

completion

true

PSVenmoContextInitializeBlock

This block is a type alias for a completion handler that receives as parameter a Result object.

public typealias PSVenmoContextInitializeBlock = (Result<PSVenmoContext, PSError>) -> Void

The initialize method returns the a Result that represents either a PSVenmoContext instance when successful either an error object. 

Usage Example

PSVenmoContext.initialize(
currencyCode: "USD",
accountId: "<account-id>",
renderType: .native
) { [weak self] result in
DispatchQueue.main.async { [weak self] in
guard let self else { return }
switch result {
case let .success(venmoContext):
self.venmoContext = venmoContext
case .failure:
break
}
}
}

Initialize Exceptions

 

Error code Display message Detailed message Comments

9061

There was an error (9061), please contact our support.

Invalid account id for ${paymentMethod}

AccountId is present, but is not configured for the wanted payment context.

9101

 There was an error (9101), please contact our support.

Invalid accountId parameter

The SDK checks if the accountId string has only numbers.

9055

 There was an error (9055), please contact our support.

Invalid currency parameter

The SDK checks if currency param that has 3 letters only.

This exception is thrown when the server responds with code 5001.

9085

 There was an error (9085), please contact our support.

There are no available payment methods for this API key.

 

9084

 There was an error (9084), please contact our support.

Failed to load available payment methods

Triggered when internal server error response for getting the payment methods api call.

9073

 There was an error (9073), please contact our support.

Account not configured correctly.

The error is a result of an improperly created merchant account configuration:

  • Merchant has no account or payment methods configured.
  • The account that is provided on initialize is not configured for the merchant.

Tokenization

This tokenize method returns a PaymentHandle result, which will resolve to a single-use payment handle representing the user's sensitive card data. This handle can be used by the Payments API to take payments. Single-use handles are valid for only 15 minutes and are not consumed by verification. See Payments with a Handle for more details.

Tokenize callback signature

The tokenize function has the following signature:

/// Paysafe Core Venmo tokenize method. 
///
/// - Parameters:
///   - options: PSVenmoTokenizeOptions
///   - completion: PSTokenizeBlock
public func tokenize(
    using options: PSVenmoTokenizeOptions,
    completion: @escaping PSTokenizeBlock
)

The tokenize() function provides a convenient method for tokenizing sensitive card data, allowing secure payment processing. Upon invocation, this function returns a completion handler that resolves to a single-use payment handle, which represents the user's sensitive card data. This handle can be utilized by the Payments API for payment transactions. It's important to note that single-use handles are valid for only 15 minutes and are not consumed during verification.

Parameters:

  • options: An instance of PSVenmoTokenizeOptions containing various parameters for tokenization, such as the payment amount, transaction type, account ID and Venmo configuration.
  • completion: A completion handler of type PSTokenizeBlock, which is executed once the tokenization process is complete. The completion handler provides the single-use payment handle or any error encountered during the tokenization process.

PSVenmoTokenizeOptions

The PSVenmoTokenizeOptions structure provides a comprehensive set of options for configuring the tokenization process. These options include:

Parameter Required Type Description

amount

true

Double

The payment amount is in minor units to charge the customer's card. Use the correct minor units amount for the merchant account currency.

For example, to process US $10.99, this value should be 1099. To process 1000 Japanese Yen, this value should be 1000. To process 10.139 Tunisian dinar, this value should be 10139.

Min = 1

Max = 999999999

When using 3DS 2 (i.e. useThreeDSecureVersion2= true), amount with value: "0" can be passed.

currencyCode

true

String

The currencyCode accepts 3 letter abbreviations of the ISO standard currencies.

accountId

true

String

The id of the selected merchant account to use to process the payment.

If you are a merchant, then this field is required only if you have more than one account configured for the same payment method and currency. If you are a partner using a shared API key, then this field is mandatory.

transactionType

true

TransactionType

This specifies the transaction type for which the Payment Handle is created. Possible values are:

  • payment - Payment Handle is created to continue the Payment.
  • standaloneCredit - Payment Handle is created to continue the standalone credit.
  • originalCredit - Payment Handle is created to continue the original credit.
  • verification - Payment Handle is created to continue the verification request.

merchantRefNum

true

String

A unique identifier is provided by the merchant for every transaction in Paysafe iOS SDK.

billingDetails

false

BillingDetails

Card billing address - additional details for the billingDetails object can be found in the Payments API documentation.

profile

false

Profile

This is the profile of the customer - additional details for the profile object can be found in the Payments API documentation.

merchantDescriptor

false

MerchantDescriptor

This is a merchant descriptor that is displayed on a customer’s card statement.

shippingDetails

false

ShippingDetails

This is the shipping usage information.

consumerMessage

false

String

The user can send a note to payer for payment

venmo

true

VenmoAdditionalData

Venmo configuration

 

VenmoAdditionalData

consumerId

true

String

The unique merchant's consumer id and must be unique per consumer.

merchantAccountId

false

String

You can set up multiple accounts with Braintree, and each account can settle funds into a different bank account. This parameter therefore allows you to control which of your bank accounts is used to receive settlement.

profileId

false

String

You can set up multiple profiles with Braintree, where each profile shows the consumer a different logo and description during checkout on the Venmo app, and on the Venmo statement. This parameter therefore allows you to vary the consumer experience (for example, if you have multiple brands, you can display a different logo for each).

Usage example

/// Payment amount in minor units
let amount = totalPrice * 100
let options = PSVenmoTokenizeOptions(
    amount: amount,
    currencyCode: "USD",
    transactionType: .payment,
    merchantRefNum: PaysafeSDK.shared.getMerchantReferenceNumber(),
    accountId: "<account-id>",
    venmo: VenmoAdditionalData(
        consumerId = "cosumer@gmail.com",|
        merchantAccountId": "BankAccount2",
        profileId": 1953896702662410200
     )
)
venmoContext.tokenize(
    using: options
) { [weak self] tokenizeResult in
    DispatchQueue.main.async { [weak self] in
        guard let self else { return }
        switch tokenizeResult {
        case let .success(paymentHandleResponse):
          /// handle paymentHandleResponse
        case let .failure(error):
            alertTexts = ("Error", "\(error.localizedDescription)")
            presentAlert = true
        }
    }
}

 

Tokenization exceptions

Error code Display message Detailed message Comments

9003

There was an error (9003), please contact our support.

Invalid ${field} field value(s).

*added "field" word, *added "value(s)" instead of "value"

 

Thrown when merchant skips field validations and tries to tokenize invalid using fields.

 

Important:

This exception is thrown also when the backend request fails with

  • HTTP 400
  • the error code in the response is either 7508 or 5068

 

5068 - Either you submitted a request that is missing a mandatory field or the value of a field does not match the format expected.

7508 - You submitted an invalid card number or brand or combination of card number and brand with your request.

 

9054

There was an error (9054), please contact our support.

Amount should be a number greater than 0 no longer than 11 characters

The amount value should be a positive number.

9136

There was an error (9136), please contact our support.

Tokenization is already in progress.

Whenever merchant calls tokenize before the previous one has completed

9098

There was an error (9098), please contact our support.

Invalid parameter in merchantDescriptor.dynamicDescriptor

String value should have <= 20 characters.

9099

There was an error (9099), please contact our support.

Invalid parameter in merchantDescriptor.phone

String value should have <= 13 characters.

9112

There was an error (9112), please contact our support.

Profile firstName should be valid

String value should have <= 80 characters.

9113

There was an error (9113), please contact our support.

Profile lastName should be valid

String value should have <= 80 characters.

9119

There was an error (9119), please contact our support.

Profile email should be valid

Use the following regex to check:
^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$

5042/5068

There was an error (5042/5068), please contact our support.

There was an error (5042/5068), please contact our support.

A system error has occurred, indicating a problem between Paysafe and Venmo.

A text string in the response provides more details about the error.

5040

There was an error (5040), please contact our support.

Venmo accounts are not accepted by this merchant account

A setup error has occurred, indicating that you haven't been set up properly with Venmo.

3047/ 3048/ 3049

There was an error (3047/ 3048/ 3049), please contact our support.

The transaction was declined because the amount exceeds the floor limit. 

The transaction was declined.

For declines and amounts in the 3000s for failed transactions.