# Express SDK

### Quick demo

Check out our demo page to see the flow in action.

{% embed url="<https://js.sandbox.sensepass.com/sp-ecom-express-sdk.html>" %}

{% hint style="info" %}
This is a checkout page example with the Express SDK with the billing & shipping information filled and the order is ready to place.

The payment options responded with the customer's information used to speed up the checkout process.
{% endhint %}

<p align="center"><img src="https://3556089516-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MbqMA3Kf8t2xEX9F6y9%2Fuploads%2FZailMRtYxchTTVUsprnH%2Fac460ff59c85c50b1e1d9abc489e3cf8edd53c0eace1a20ac07f984552e17a40.jpg?alt=media&#x26;token=ce860a6c-3107-4ef0-986b-7e8c789c1a6a" alt=""></p>

***

### Configuration

{% hint style="info" %}
You can copy-paste the (relevant) following HTML code to your checkout page to get going.

* Note that the current widget configuration is set up to use the mock client-id - and replace it with yours.
  {% endhint %}

{% code lineNumbers="true" expandable="true" %}

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>SensePass Express SDK</title>
    <!--Set the SDK script-->
    <script src="https://js.sensepass.com/scripts/sensepass-front-end-express@1.0.0.sdk.js"></script>
</head>
<body>
    <!--Set the SDK element-->
    <sp-ecom-sdk-express></sp-ecom-sdk-express>

    <script>
        // Wait for the custom element to be defined
        customElements.whenDefined('sp-ecom-sdk-express').then(() => {
            const widget = document.querySelector('sp-ecom-sdk-express');
            
            // Initialize the widget with your configuration
            widget.props = {
                clientId: "SensePassSDKGeneralClientId", // location's client-id
                amount: "12.58",
                currency: "USD",
                logs: true, // enable SDK console logs
                methodType: "manual_capture", // or "authorize" | "tokenize"
                mode: "sandbox", // or "production"
                cssUrl: "https://js.sensepass.com/express-sdk.css", // download to customize your own css
                // Event handlers
                onReady: (detail) => console.log('SDK Ready:', detail),
                onShow: (detail) => console.log('Payment Shown:', detail),
                onPay: (detail) => console.log('Payment Data:', detail), // finalize the payment in your backend (commit request)
                onError: (detail) => console.error('Payment Error:', detail)
            };
        });
    </script>
</body>
</html>
```

{% endcode %}

***

### Payment Data

{% hint style="info" %}
Example of a response after paying with Google Pay
{% endhint %}

{% code lineNumbers="true" expandable="true" %}

```json
{
  "code": 27,
  "method": "googlepay",
  "timestamp": "2020-02-20T20:20:20.202Z",
  "transactionNumber": "1c3ff55c9d299cddbcc6d6fd929c63c1628bc25be2ab2c4c0cf87db9",
  "billingInformation": {
    "fullName": "Card Holder Name",
    "firstName": "Card",
    "lastName": "Holder Name",
    "addressLine1": "1600 Amphitheatre Parkway",
    "addressLine2": "",
    "city": "Mountain View",
    "state": "CA",
    "postalCode": "94043",
    "country": "US",
    "email": "john.doe@gmail.com"
  },
  "shippingInformation": {
    "fullName": "US User",
    "firstName": "US",
    "lastName": "User",
    "addressLine1": "1600 Amphitheatre Parkway1",
    "addressLine2": "",
    "city": "Mountain View",
    "state": "CA",
    "postalCode": "94043",
    "country": "US",
    "email": "john.doe@gmail.com"
  }
}
```

{% endcode %}

### Customization

{% hint style="info" %}
This code sample demonstrates how to customize the appearance of the Express Widget's payment buttons. Save & link this file in your HTML *after* the widget's script to ensure styles are applied.

The widget's internal CSS provides basic styling. This file allows you to override and enhance it.

Key selectors:

* .payment-btn: The main button element.
* .payment-logo: The  tag for the payment method logo.
* .payment-label: The tag for the payment method text label.

You can also target specific payment methods using the `part` attribute:

* \[part="paypal"]
* \[part="applepay"]
* \[part="googlepay"]
  {% endhint %}

{% code lineNumbers="true" expandable="true" %}

```css
/* Logo-only style with light background for visibility */
.payment-btn {
    position: relative;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    padding: 12px 20px;
    min-height: 48px;
    background-color: #ffffff;
    border: 1px solid #e0e0e0;
    border-radius: 6px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
    transition: all 0.2s ease;
}

.payment-logo {
    height: 24px;
    width: auto;
    max-width: 120px;
    object-fit: contain;
}

/* Hide the text label to show logo only */
.payment-label {
    display: none;
}

/* Hover state */
.payment-btn:hover:not([disabled]) {
    border-color: #c0c0c0;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    background-color: #f9f9f9;
}

/* Disabled state */
.payment-btn[disabled] {
    opacity: 0.5;
    cursor: not-allowed;
    background-color: #f5f5f5;
}

/* Show spinner overlay when button is not clickable (canPay = false) - initialization loading */
.payment-btn:not([data-can-pay="true"]) {
    position: relative;
}

.payment-btn:not([data-can-pay="true"])::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(255, 255, 255, 0.5);
    z-index: 10;
    border-radius: inherit;
}

.payment-btn:not([data-can-pay="true"])::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 24px;
    height: 24px;
    margin: -12px 0 0 -12px;
    border: 3px solid #e0e0e0;
    border-top: 3px solid #007bff;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
    z-index: 11;
}

/* Payment processing state - different visual treatment */
.payment-btn[data-processing="true"] {
    position: relative;
    background-color: white;
    cursor: not-allowed;
    opacity: 1;
}

/* Disabled state when other payment is processing */
.payment-btn[data-other-processing="true"] {
    opacity: 0.5;
    cursor: not-allowed;
}

.payment-btn[data-processing="true"]::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: transparent;
    backdrop-filter: blur(3px);
    z-index: 10;
    border-radius: inherit;
}

/* Add green spinner for processing state */
.payment-btn[data-processing="true"]::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 24px;
    height: 24px;
    margin: -12px 0 0 -12px;
    border: 3px solid #e0e0e0;
    border-top: 3px solid #28a745;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
    z-index: 12;
}

/* Spinner keyframes */
@keyframes spin {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}

/* Pulse animation for processing state */
@keyframes pulse {
    0%, 100% {
        opacity: 0.1;
    }
    50% {
        opacity: 0.3;
    }
}

/* Bright pulse animation for processing state */
@keyframes pulseBright {
    0%, 100% {
        opacity: 0.6;
    }
    50% {
        opacity: 1;
    }
}


/* Optional: Specific styling for individual payment methods */

/* PayPal - slightly smaller logo */
[part="paypal"] .payment-logo {
    background-color: #ffffff;
}

/* Apple Pay - ensure good contrast */
[part="applepay"] {
    background-color: #ffffff;
}

/* Google Pay - ensure good contrast */
[part="googlepay"] {
    padding-top: 8px;
    padding-bottom: 8px;
}

[part="googlepay"] .payment-logo {
    height: 32px;
}

```

{% endcode %}
