Merchant-initiated authentication (3RI)

Use 3D Secure (3DS) Requestor Initiated (3RI) authentication to generate the authentication data a merchant-initiated transaction needs for authorization, without requiring the customer to be present.

IntroductionAnchorIcon

3DS Requestor Initiated (3RI), also called merchant-initiated authentication, generates the authentication data a merchant needs for authorization by referencing details from the customer's original authentication. 3RI can provide a liability shift, and can increase authorization rates, for merchant-initiated transactions.

Use casesAnchorIcon

3RI supports five merchant-initiated transaction scenarios. Each scenario walks through the sequence of customer-initiated and merchant-initiated requests, so you can identify which pattern matches your integration.

RecurringAnchorIcon

Use this pattern for services that require regular payments, such as subscriptions or bill payments. After the customer authenticates an initial transaction, you can process the subsequent payments by referencing the authentication details of that initial transaction.

Example: Charging the first payment up frontAnchorIcon

A customer enrolls in a $15-per-month subscription plan with a merchant. The merchant charges the first subscription payment up front. During checkout, a customer-initiated 3DS authentication completes, followed by a customer-initiated transaction (CIT):

  • 3DS: $15
  • CIT: $15

After 1 month, a merchant-initiated 3DS (3RI) authentication completes, followed by a merchant-initiated transaction (MIT):

  • 3RI:* $15
  • MIT:* $15

* Continues every month until the customer cancels the subscription.

Example: Free trialAnchorIcon

A customer enrolls in a $100-per-quarter subscription plan with a merchant. The first two months of the subscription are free.

During checkout, a customer-initiated 3DS authentication completes, followed by a Verification:

  • 3DS: $100
  • Verification: $0

After 2 months, a merchant-initiated 3DS (3RI) authentication completes, followed by a merchant-initiated transaction (MIT):

  • 3RI:* $100
  • MIT:* $100

* Continues every 3 months until the customer cancels the subscription.

InstallmentAnchorIcon

Use this pattern for services that let customers pay in installments. After the customer authenticates an initial transaction, you can process the subsequent installment payments by referencing the authentication details of that first transaction, so the customer doesn't need to re-authenticate each time.

Example

A customer buys a $6,000 item online from a merchant and enrolls to pay for it over 12 monthly installments.

At checkout:

  • 3DS: $6,000
  • CIT: $500

After 1 month:

  • 3RI:* $500
  • MIT:* $500

* Continues every month for the remaining 11 installments.

Split shipmentAnchorIcon

Use this pattern when an order needs to be divided into multiple shipments, often due to logistical constraints. Authenticate the initial customer-initiated 3DS for the entire order amount, then submit a separate 3RI request for each subsequent shipment.

Example

A customer purchases 3 items from an ecommerce store: Item A worth $20, Item B worth $30, and Item C worth $50. Only Item A is available at checkout. The merchant ships Item B after 15 days and Item C after 30 days.

During checkout, a customer-initiated 3DS authentication completes for the collective amount, followed by a customer-initiated transaction (CIT) for Item A:

  • 3DS: $100 (collective amount)
  • CIT: $20 (Item A)

After 15 days, a merchant-initiated 3DS (3RI) authentication and a merchant-initiated transaction (MIT) complete for Item B:

  • 3RI: $30
  • MIT: $30 (Item B)

After 30 days, a merchant-initiated 3DS (3RI) authentication and a merchant-initiated transaction (MIT) complete for Item C:

  • 3RI: $50
  • MIT: $50 (Item C)

Note: The aggregated amount of your 3RI requests shouldn't exceed the amount of the original customer-initiated 3DS authentication.

Delayed shipmentAnchorIcon

Use this pattern to maintain liability protection beyond 90 days. Submit a 3RI request to generate a new CAVV, valid for another 90 days.

Example

A customer purchases a $250 item from an online store. The item isn't available and can only ship after 120 days, which exceeds the 90-day expiration of a regular 3DS CAVV.

During checkout, a customer-initiated 3DS authentication completes, followed by a Verification:

  • 3DS: $250
  • Verification: $0

Before 90 days*, a merchant-initiated 3DS (3RI) authentication completes:

  • 3RI: $250

* Complete the 3RI request before the CAVV from the customer-initiated 3DS authentication expires. After 120 days, a merchant-initiated transaction (MIT) completes:

  • MIT: $250

Payment with multiple merchantsAnchorIcon

Use this pattern when multiple parties need to process authorizations from a single customer-initiated authentication. The merchant who completed the initial authentication, also known as the Agent, must submit a separate 3RI request for each additional merchant involved in fulfilling the order.

Example

A customer books a package on a travel agent website for a hotel stay worth $2,500 and airline tickets costing $1,000. The travel agent charges $500 in commission, and must submit a unique 3RI request to obtain a unique CAVV for each merchant.

During checkout, a customer-initiated 3DS authentication completes for the collective amount, followed by a customer-initiated transaction (CIT) for the travel agent's commission:

  • 3DS: $4,000 (collective amount)
  • CIT: $500 (travel agent's commission)

The travel agent completes a merchant-initiated 3DS (3RI) authentication to generate a new CAVV for the hotel:

  • 3RI: $2,500

The hotel completes a merchant-initiated transaction (MIT) by embedding the CAVV the travel agent generated:

  • MIT: $2,500 (hotel stay)

The travel agent completes a merchant-initiated 3DS (3RI) authentication to generate a new CAVV for the airline:

  • 3RI: $1,000

The airline completes a merchant-initiated transaction (MIT) by embedding the CAVV the travel agent generated:

  • MIT: $1,000 (airline ticket)

PrerequisitesAnchorIcon

Before you start, you need:

  • A Braintree server SDK: Java SDK (version 3.35 or later) or .NET SDK (version 5.26.0 or later), or access to the GraphQL API.
  • A completed customer-initiated 3DS authentication to reference in your first merchant-initiated request.

Complete a merchant-initiated authenticationAnchorIcon

Completing a 3RI integration takes four steps. First, the customer checks out using a customer-initiated 3DS authentication and a customer-initiated transaction (CIT). Later, you complete a merchant-initiated 3DS (3RI) authentication and a merchant-initiated transaction (MIT).

1. Complete a customer-initiated 3DS authenticationAnchorIcon

Before you can complete 3RI, send the appropriate authenticationIndicator value during the customer-initiated 3DS lookup:

  1. Recurring: "02"
  2. Installment: "03"
  3. Split shipment: "08"
  4. Delayed shipment: "09"
  5. Payment with multiple merchants: "85"
  1. JavaScript
async function verifyCard() {
  try {
    const response = await threeDSecure.verifyCard(
      {
        amount: '500.00',
        nonce: NONCE_FROM_INTEGRATION,
        bin: BIN_FROM_INTEGRATION,
        additionalInformation: {
          authenticationIndicator: "08"
        },
      onLookupComplete: function (data, next) {
        // use 'data' here, then call 'next()'
        next();
      }
    });
  
    const liabilityShifted = response.threeDSecureInfo.liabilityShifted;  // true || false
    const liabilityShiftPossible = response.threeDSecureInfo.liabilityShiftPossible;  // true || false
  } catch (err) {
    // handle error
  }
}

2. Complete a customer-initiated transaction (CIT) or VerificationAnchorIcon

Customer-initiated transaction (CIT)AnchorIcon

Embed 3DS data in the transaction by passing either a 3DS upgraded nonce or an authentication ID associated with the lookup.

  1. Java
  2. C#
  3. GraphQL
TransactionRequest request = new TransactionRequest()
  .amount(new BigDecimal("10.00"))
  .paymentMethodNonce(nonceWithout3ds)
  .threeDSecureAuthenticationId(threeDSecureAuthenticationId)
  .options()
    .submitForSettlement(true)
    .done();

Result<Transaction> result = gateway.transaction().sale(request);

VerificationAnchorIcon

Create a new customer with a payment method by passing either a 3DS upgraded nonce or an authentication ID associated with the lookup. See the customer guide for more details.

  1. Java
  2. C#
  3. GraphQL
CustomerRequest request = new CustomerRequest()
  .paymentMethodNonce(nonceFromTheClient)
  .threeDSecureAuthenticationId(threeDSecureAuthenticationId)
  .firstName("Fred")
  .lastName("Jones")
  .creditCard()
    .options()
      .verifyCard(true)
      .done()
    .done();

Result<Customer> result = gateway.customer().create(request);

Alternatively, create a payment method for an existing customer by passing either a 3DS upgraded nonce or an authentication ID associated with the lookup. See the payment method guide for more details.

  1. Java
  2. C#
  3. GraphQL
PaymentMethodRequest request = new PaymentMethodRequest()
  .customerId("the_customer_id")
  .paymentMethodNonce(nonceFromTheClient)
  .threeDSecureAuthenticationId(threeDSecureAuthenticationId)
  .options()
    .verifyCard(true)
  .done();
  
Result<? extends PaymentMethod> result = gateway.paymentMethod().create(request);

3. Complete a merchant-initiated 3DS (3RI) authenticationAnchorIcon

Send the merchantInitiatedRequestType field to indicate the type of 3RI request:

  1. Recurring: "recurring"
  2. Installment: "installment"
  3. Split shipment: "split_shipment"
  4. Delayed shipment: "delayed_shipment"
  5. Payment with multiple merchants: "payment_with_multiple_merchants"

Scenario: Customer-initiated 3DS completed at BraintreeAnchorIcon

Send the authenticationId of the customer-initiated 3DS authentication completed at Braintree as the priorAuthenticationId in the 3RI lookup.

  1. Java
  2. C#
  3. GraphQL
ThreeDSecureLookupRequest request = new ThreeDSecureLookupRequest();
request.amount("10.00");
request.merchantInitiatedRequestType("split_shipment");
request.priorAuthenticationId(<PRIOR_AUTHENTICATION_ID>);

Result<ThreeDSecureLookupResponse> result = gateway.threeDSecure().lookup(request);

PaymentMethodNonce paymentMethod = result.getTarget().getPaymentMethod();
String authenticationId = paymentMethod.getThreeDSecureInfo().getThreeDSecureAuthenticationId();

Scenario: Customer-initiated 3DS completed externallyAnchorIcon

Send the authentication details (DS Transaction ID, ACS transaction ID, and so on) of the customer-initiated 3DS authentication completed externally as the priorAuthenticationDetails in the 3RI lookup.

  1. Java
  2. C#
  3. GraphQL
Calendar authTime = Calendar.getInstance();
authTime.set(2024, Calendar.FEBRUARY, 10, 22, 45, 30);

ThreeDSecureLookupPriorAuthenticationDetails priorAuthenticationDetails = new ThreeDSecureLookupPriorAuthenticationDetails()
  .acsTransactionId("acs-transaction-id")
  .authenticationMethod("02")
  .authenticationTime(authTime)
  .dsTransactionId("ds-transaction-id");

ThreeDSecureLookupRequest request = new ThreeDSecureLookupRequest();
request.amount("10.00");
request.merchantInitiatedRequestType("split_shipment");
request.priorAuthenticationDetails(priorAuthenticationDetails);

Result<ThreeDSecureLookupResponse> result = gateway.threeDSecure().lookup(request);

PaymentMethodNonce paymentMethod = result.getTarget().getPaymentMethod();
String authenticationId = paymentMethod.getThreeDSecureInfo().getThreeDSecureAuthenticationId();

The authenticationMethod field indicates the mechanism used to authenticate the customer-initiated 3DS request. The SDK supports these values:

  1. Frictionless:"01"
  2. Challenge:"02"
  3. AVS verified:"03"
  4. Other issuer method:"04"

4. Complete a merchant-initiated transaction (MIT)AnchorIcon

Pass the following transactionSource values to indicate that the transaction request is merchant-initiated:

  1. Recurring: "recurring"
  2. Installment: "installment"
  3. Split shipment: "unscheduled"
  4. Delayed shipment: "unscheduled"
  5. Payment with multiple merchants: "unscheduled"

Scenario: Recurring, split shipment, or delayed shipmentAnchorIcon

Embed 3RI data in a transaction by passing either a 3DS upgraded nonce or an authentication ID associated with the 3RI lookup.

  1. Java
  2. C#
  3. GraphQL
TransactionRequest request = new TransactionRequest()
  .amount(new BigDecimal("10.00"))
  .paymentMethodNonce(nonceWithout3ds)
  .threeDSecureAuthenticationId(threeDSecureAuthenticationId)
  .transactionSource("unscheduled")
  .options()
    .submitForSettlement(true)
    .done();

Result<Transaction> result = gateway.transaction().sale(request);

Scenario: Payment with multiple merchantsAnchorIcon

The merchant on record must embed the newly generated CAVV from the 3RI lookup in the threeDSecurePassThru field of the transaction.

  1. Java
  2. C#
  3. GraphQL
TransactionRequest request = new TransactionRequest()
  .amount(new BigDecimal("10.00"))
  .paymentMethodNonce(nonceWithout3ds)
  .transactionSource("unscheduled")
  .threeDSecurePassThruRequest()
    .cavv(<CAVV_FROM_3RI>)
    .eciFlag("05")
    .dsTransactionId("some-ds-transaction-id")
    .authenticationResponse("some-auth-response")
    .directoryResponse("some-directory-response")
    .cavvAlgorithm("algorithm")
    .done()
  .options()
    .submitForSettlement(true)
    .done();

Result<Transaction> result = gateway.transaction().sale(request);