---
title: Create 3D Secure Transaction
slug: payments/create-3d-secure-transaction
docTags: 
createdAt: 2024-03-21T11:05:27.502Z
---

:::hint{type="info"}
Note: This is currently only supported for the Stripe payment processor.
:::

To create a Transaction in the Payment processor with 3DS secure authentication, please follow the below process:

1. Call the "ChargeProcessor" action as you normally would. See [here](https://app.archbee.com/docs/36_eQf-KpERkq02_og2jt/ZwFku6Ke5vu5EsuPYRmEY). This is the normal flow for any charge.
   1. If the related Payment method has 3D secure authentication enabled, the response will return an **authenitcation\_url**.&#x20;
      1. *\{&#xD;*&#xA;*&#x20; "authentication\_url" : "https\://hooks.stripe.com/...",         &#xD;*&#xA;*}*
   2. The **authentication\_url&#x20;**&#x69;s a link to a form that will do the 3D Secure authorization. This needs to be loaded in an iFrame hosted by you.
   3. After the 3DS authentication, Stripe will redirect to Breadwinner to process the success or failure of the authentication.
2. After the completion of additional authentication, Breadwinner will post the payment\_intent\_id to your top-level page (the one hosting the iFrame)
   1. *window\.parent.postMessage(\{message: '3DS-authentication-complete', params: \{payment\_intent: payment\_intent\_id}, '\*');*
3. You must extract **payment\_intent** from postMessage and then retrieve the transaction with the "fetchTransaction" Global API action (example below). This will create the charge in Salesforce if successful or return a 402 error if the authentication fails.



Example of "ChargeProcessor" Global API action request and response for a 3DS credit card.

:::CodeblockTabs
```apex
Map<String, Object> chargeData = new Map<String, Object>();
        chargeData.put('processorCustomerId', 'processorCustomerId'); 
        chargeData.put('paymentMethodId', 'paymentMethodId'); 
       
        chargeData.put('amount', '123.12'); 
        chargeData.put('chargeCurrency', 'USD'); 
        chargeData.put('description', 'test payment'); 
        chargeData.put('paymentMethodType', 'Card'); 
                
        //  Initializing the RequestJSON Data to be passed.
        Map<String, Object> requestJSONMap = new Map<String, Object>();
        requestJSONMap.put('transactions', new List<Object>{chargeData});
        String reqJSON = JSON.serialize(requestJSONMap);
        
        Map<String, Object> reqObj = new Map<String, Object>();
        reqObj.put('version','1.0');
        reqObj.put('action','ChargeProcessor');
        reqObj.put('processorId', 'processorId');
        reqObj.put('requestJSON',reqJSON);
        
        //  Placing a request to Breadwinner Global API
        Map<String,Object> resp = bw_payments.BreadwinnerPaymentsAPI.call(reqObj);
        System.debug(resp);

```

```json
{
  Action=ChargeProcessor,
  Version=1.0,
  responseJSON={
     "authentication_url" : "https://hooks.stripe.com/..."
  },
  statusCode=200,
  timestamp=1711117871901,
  validRequest=true
}
```
:::

Example of "FetchTransaction" Global API action request and response for authentication success and failure.

:::CodeblockTabs
```apex
Map<String, Object> chargeData = new Map<String, Object>();
chargeData.put('paymentIntentId', 'paymentIntentId');
                
//  Initializing the RequestJSON Data to be passed.
Map<String, Object> requestJSONMap = new Map<String, Object>();
requestJSONMap.put('transaction', new List<Object>{chargeData});
String reqJSON = JSON.serialize(requestJSONMap);
        
Map<String, Object> reqObj = new Map<String, Object>();
reqObj.put('version','1.0');
reqObj.put('action','FetchTransaction');
reqObj.put('processorId', 'processorId');
reqObj.put('requestJSON',reqJSON);
        
//  Placing a request to Breadwinner Global API
Map<String,Object> resp = bw_payments.BreadwinnerPaymentsAPI.call(reqObj);
System.debug(resp);

```

Response for 3DS Success

```json
{
  Action=FetchTransaction,
  Version=1.0,
  responseJSON={
    "transactions": [
      {
        "taxAmount": null,
        "status": "SUCCEEDED",
        "staffName": null,
        "salesforcePaymentMethodId": "salesforcePaymentMethodId",
        "salesforceId": "salesforceId",
        "salesforceCustomerId": "salesforceCustomerId",
        "salesforceContact": null,
        "salesforceAccount": null,
        "referenceId": null,
        "receiptUrl": "https://pay.stripe.com/receipts/payment/receiptUrl",
        "receiptNumber": null,
        "receiptEmail": null,
        "processorType": "Stripe",
        "processorOrgId": "processorOrgId",
        "processorId": "processorId",
        "processorCustomerId": "processorCustomerId",
        "processingFee": null,
        "paymentMethodType": null,
        "paymentMethodId": null,
        "paymentIntentId": null,
        "locationId": null,
        "idempotencyKey": null,
        "errorMessage": null,
        "description": "test payment",
        "createdVia": "Breadwinner",
        "createdDateInProcessor": "2024-03-21T10:32:48.000Z",
        "chargeStatus": null,
        "chargeIsTaxExempt": null,
        "chargeCurrency": "USD",
        "captured": true,
        "billingStreetAddress2": "",
        "billingStreetAddress1": "",
        "billingPostalCode": "",
        "billingCountry": "IN",
        "billingCity": "",
        "applicationFee": null,
        "amountRefunded": 0.00,
        "amount": 123.12
      }
    ]
  },
  statusCode=200,
  timestamp=1711022730348,
  validRequest=true
}
```

Response for 3DS Failure

```none
{
  Action=FetchTransaction,
  Version=1.0,
  responseJSON={
    "errors": [
      {
        "message": "The provided PaymentMethod has failed authentication. Please try again or choose a different payment method.",
        "detail": null,
        "code": "402"
      }
    ]
  },
  statusCode=200,
  timestamp=1711542121243,
  validRequest=true
}
```
:::



