Enroll a PayPal payment account in an existing wallet

Allow users who already have a registered mobile wallet to add PayPal as a valid payment tender in that wallet.

Payment account enrollment screen flow

Figure 3: Payment account enrollment screen flow

As shown in Figure 3, the app provides an operator specific to the PayPal account type. When selected, call the PayPal Braintree SDK client and invoke the app switch; the Braintree SDK client checks whether the One-Touch client is installed on the device, and displays the PayPal login and consent screens in the app or in a browser, accordingly. In either case, once the user consents to the integration, the Braintree SDK client returns the BTPaymentAccountNonce and switches the focus back to the mobile wallet app.

Figure 4 shows the data process flow involved in the assisted registration.

PayPal Account enrollment sequence diagram

Figure 4: PayPal account enrollment sequence diagram

The next sections provide implementation and samples for each of the relevant calls depicted in Figure 4.

Start enrollment

Use these commands to begin enrollment and implement the success and failure responses.

  1. Invoke the specific Paydiant SDK call to start payment account enrollment for your device.

    OS Command
    iOS startPaymentAccountEnrollment:(PDStartPaymentAccountEnrollmentRequest *)request;
    Android startPaymentAccountEnrollment (StartPaymentAccountEnrollment startPaymentAccountEnrollment);

    Within each of the parameter objects, the following data must be passed:

    iOS Property Description
    enrollmentType Required Enum
    A value specifying whether Paydiant will be the system of record for the payment account. For this use case, the only supported value is kPDEnrollmentTypeProvision
    paymentAccountTypeUri Required String
    Paydiant’s unique identifier for the type of payment account.
    paymentAccountNetworkTypeUri Required String
    Paydiant’s unique identifier for the payment processor.
    additionalData Required Array
    A set of property instances that define other data required for the enrollment. For this use case, you must define the following:
    key = NICKNAME
    value = PayPal
  2. Implement the device OS-specific Paydiant SDK callback to handle the success response.

    OS Command
    iOS startPaymentAccountEnrollmentCompletionBlock:(PDStartPaymentAccountEnrollmentResponse *)response
    Android onStartPaymentAccountEnrollmentSuccess (PaymentAccountEnrollment paymentAccountEnrollment)

    Within either respective parameter object, the following data may be returned:

    Property Description
    enrollmentState Enum
    An EnrollmentState enum value indicating whether the enrollment process is complete or requires another step. For this step in the implementation, the value for this parameter will be MORE_INFO.
    paydiantCorrelationId String
    Paydiant’s unique identifier for the enrollment process. Required for each step in the enrollment to correctly associate all related data.
    externalCorrelationId String
    PayPal’s unique identifier for the enrollment; required for all related enrollment calls to ensure accurate processing and logging.
    additionalEnrollmentData Array/List
    The set of key/value definitions representing properties relevant for the enrollment. For this step in the implementation, PayPal returns the btClientToken within this property.

    Configure the success response to initialize Braintree SDK client using the returned token value.

  3. Implement the device OS-specific Paydiant SDK callback to handle the failure response.

    OS Command
    iOS startPaymentAccountEnrollmentFailureBlock:(PDPaydiantError *managePaymentInstrumentError);
    Android onStartPaymentAccountEnrollmentError (PaydiantException exception)

    Within each of the parameter objects, the following data may be returned:

    Property Description
    Description String
    The basic error description returned by the SDK.
    statusMessage String
    The Mobile Gateway description associated with the returned statusCode.
    statusCode Integer
    The code representing the failure reason from the Mobile Gateway.
    rawErrorDescription String
    An error description reported by the device operating system.
    localizedDescription String
    A custom message relevant to the error.
    errorInformation String
    An object containing error information as obtained from an external party, such as the response from a payment provider.

Samples

Sample Start PayPal Enrollment in Existing Wallet for iOS

- (void)addPayPal:(PDTenderType *)tender {

    PDStartPaymentAccountEnrollmentRequest * request = [[PDStartPaymentAccountEnrollmentRequest alloc] init];
    request.enrollmentType = kPDEnrollmentTypeProvision;
    request.paymentAccountTypeUri = tender.paymentAccountType.paymentAccountTypeUri;
    request.paymentAccountNetworkTypeUri = tender.paymentAccountNetworkType.paymentAccountNetworkTypeUri;

    NSMutableArray * additionalInfo = [[NSMutableArray alloc] init];

    PDStartPaymentAccountEnrollmentAdditionalData * instances = PDStartPaymentAccountEnrollmentAdditionalData alloc] init];
    instances.additionalDataKey = @"NICK_NAME";
    instances.additionalDataValue = @"PayPal";
    [additionalInfo addObject: instances];

    request.additionalData = additionalInfo;

    PDManagePaymentInstrumentsCoordinator * managePayInstr = [[PDManagePaymentInstrumentsCoordinator alloc] init];
    [CommonUtil showProgressIndicatorOnView: self];
    [managePayInstr startPaymentAccountEnrollment: request completionBlock: ^(PDStartPaymentAccountEnrollmentResponse * response) {
        NSString *paydiantCorrelationId = response.paymentAccountEnrollment.paydiantCorrelationId;
        NSString *externalCorrelationId = response.paymentAccountEnrollment.externalCorrelationId;
        NSArray *additionalData = response.paymentAccountEnrollment.additionalEnrollmentData;

        if (additionalData.count <0) {
            PDAdditionalEnrollmentData *pdData = additionalData[0];
            NSString *btClientToken = pdData.additionalEnrollmentDataValue;
            BTAPIClient *apiClient = [[BTAPIClient alloc] initWithAuthorization: btClientToken];
            BTPayPalDriver *btPayPalDriver = [[BTPayPalDriver alloc] initWithAPIClient: apiClient];
            btPayPalDriver.appSwitchDelegate = (id) self;
            btPayPalDriver.viewControllerPresentingDelegate = (id) self;
            BTPayPalRequest *checkout = [[BTPayPalRequest alloc] init];
            [btPayPalDriver requestBillingAgreement: checkout completion: ^(BTPayPalAccountNonce * _Nullable tokenizedPayPalCheckout, NSError * _Nullable error) {
                if (error) {
                    NSLog(@"ERROR = %@", error);
                    [CommonUtil hideProgressIndicatorOnView: self];
                    [CommonUtil displayMessageWithTitle:@"Error"
                            andDescription: @"Your PayPal account could not be linked at this time. Please try again."];
                }
                else if (tokenizedPayPalCheckout) {
                    NSString * nonce = tokenizedPayPalCheckout.nonce;
                    NSLog(@"Got a nonce: %@", nonce);
                }
            }
        }
    }
}

Sample Start PayPal Enrollment in Existing Wallet for Android

{
  StartPaymentAccountEnrollment paymentAccountEnrollment = new StartPaymentAccountEnrollment();
  List AdditionalData additionalDataList = new ArrayListAdditionalData();
  AdditionalData nickNameAdditionalData = new AdditionalData();
  nickNameAdditionalData.setKey(getString(R.string.additional_data_nickname_key));
  nickNameAdditionalData.setValue(getString(R.string.additional_data_nickname_value));
  additionalDataList.add(nickNameAdditionalData);
  paymentAccountEnrollment.setAdditionalData(additionalDataList);
  paymentAccountEnrollment.setEnrollmentType(EnrollmentType.PROVISION);
  paymentAccountEnrollment.setPaymentAccountTypeUri(accountTypeURI);
  paymentAccountEnrollment.setPaymentAccountNetworkTypeUri(accountNetworkTypeURI);
  paymentAccountManagementService.startPaymentAccountEnrollment(paymentAccountEnrollment);
  Log.d(ApplicationConstants.LOG_TAG, "startPaymentAccountEnrollment()");
}

Initialize Braintree SDK client

See Initialize Braintree SDK client for samples and links to the Braintree documentation you can use to learn how to initialize the Braintree SDK client.

Continue enrollment

  1. Once the Braintree SDK returns the payment account nonce, use these commands to continue the enrollment and set the success and failure responses.

    OS Command
    iOS continuePaymentAccountEnrollment:(PDContinuePaymentAccountEnrollmentRequest *)request;
    Android continuePaymentAccountEnrollment (ContinuePaymentAccountEnrollment continuePaymentAccountEnrollment);

    Within each of the parameter objects, the following data must be passed:

    Property Description
    paydiantCorrelationId Required String
    Paydiant’s unique identifier for the enrollment, which was returned in the start enrollment response.
    externalCorrelationId Required String
    PayPal’s unique identifier for the enrollment, which was returned in the start enrollment response.
    additionalEnrollmentData Required Array/List
    A set of property instances that define other data relevant to the enrollment. For this use case, you must define the following:

    key = PAYMENT_METHOD_NONCE
    value = BTPayPalAccountNonce returned by Braintree client
  2. Implement the device OS-specific Paydiant SDK callback to handle the success response.

    OS Command
    iOS continuePaymentAccountEnrollmentCompletionBlock:(PDContinuePaymentAccountEnrollmentResponse *)response
    Android onContinuePaymentAccountEnrollmentSuccess (PaymentAccountEnrollment paymentAccountEnrollment)

    Within either respective parameter object, the following data may be returned:

    Property Description
    enrollmentState Enum
    An EnrollmentState enum value indicating whether the enrollment process is complete or requires another step. For this step in the implementation, the value for this parameter will be END.
    paydiantCorrelationId String
    Paydiant’s unique identifier for the enrollment process. This ID must be passed with each step in the enrollment to ensure that all related data is correctly associated.
    externalCorrelationId String
    PayPal’s unique identifier for the enrollment, which must be passed in all related enrollment calls going forward to ensure accurate processing and logging.
    additionalEnrollmentData Array/List
    A set of key/value definitions representing properties relevant for the enrollment. For this step in the implementation, this parameter should be null.

    Configure the success response to display a confirmation message and return to the Payment Account Summary screen.

  3. Implement the device OS-specific Paydiant SDK callback to handle the failure response.

    OS Command
    iOS continuePaymentAccountEnrollmentFailureBlock:(PDPaydiantError *managePaymentInstrumentError)
    Android onContinuePaymentAccountEnrollmentError (PaydiantException exception)

    Within each of the parameter objects, the following data may be returned:

    Property Description
    Description String
    The basic error description returned by the SDK.
    statusMessage String
    The Mobile Gateway description associated with the returned statusCode.
    statusCode Integer
    The numerical code representing the reason for failure from the Mobile Gateway.
    rawErrorDescription String
    An error description reported by the device system.
    localizedDescription String
    A custom message relevant to the error.
    errorInformation String
    Error data passed by an external party, such as the response from a payment provider.

Sample Complete PayPal Enrollment in Existing Wallet for iOS

@Override
...
PDContinuePaymentAccountEnrollmentRequest *continuePaymentAccountEnrollmentRequest =
[[PDContinuePaymentAccountEnrollmentRequest alloc] init];
NSMutableArray *additionalInfo = [[NSMutableArray alloc] init];

PDAdditionalEnrollmentData *instances = [[PDAdditionalEnrollmentData alloc] init];
instances = [[PDAdditionalEnrollmentData alloc] init];
instances.additionalEnrollmentDataKey = @"PAYMENT_METHOD_NONCE";
instances.additionalEnrollmentDataValue = nonce;

[additionalInfo addObject:instances];

continuePaymentAccountEnrollmentRequest.paydiantCorrelationId = paydiantCorrelationId;
continuePaymentAccountEnrollmentRequest.externalCorrelationId = externalCorrelationId;
continuePaymentAccountEnrollmentRequest.additionalEnrollmentData = additionalInfo;

[managePayInstr continuePaymentAccountEnrollment:continuePaymentAccountEnrollmentRequest
    completionBlock:^(PDContinuePaymentAccountEnrollmentResponse *response) {
    if (response.paymentAccountEnrollment.enrollmentState == kPDEnrollmentStateEnd) {
    [CommonUtil hideProgressIndicatorOnView:self];
    [CommonUtil displayMessageWithTitle:@"Success"
                            andDescription:@"Your PayPal Account has been added to your mobile wallet successfully."];
    [[NSNotificationCenter defaultCenter] postNotificationName:kPaymentAccountsChangedNotification object:self];
    }

} failureBlock:^(PDPaydiantError *managePaymentInstrumentsError) {
    [CommonUtil hideProgressIndicatorOnView:self];
    [CommonUtil displayError:managePaymentInstrumentsError];
}];

} else {
    [CommonUtil hideProgressIndicatorOnView:self];
    [CommonUtil displayMessageWithTitle:@"Error"
                         andDescription:@"PayPal account linking cancelled: your account has not been added to your wallet."];
    }
}];
}

Next