Snap JavaScript SDK (v2) — Quick Start Guide

Public edition • v2 • Stable

Overview

Snap’s JavaScript SDK lets you add a “Pay with Snap” option to your website. When a shopper clicks the button, a secure window opens for the application and checkout flow. When finished, the window closes and your site receives the result (for example, an applicationId on approval).

How it works
  1. Your server requests a short-lived access token from Snap and caches it (valid ~24 hours).
  2. Your webpage loads the Snap SDK v2 and initializes it with the token.
  3. On button click, you call actions.launchCheckout(transaction). Snap returns results via callbacks.

Step 1 — Verify requirements

  • Snap Developer credentials: Client ID and Client Secret.
  • A server that can make HTTPS requests and keep secrets (Node, Python, Java, and so on).
  • Frontend where you will render the Snap mark and checkout button.
  • Serve over http(s) (for example, http://localhost:5500). Avoid file:// URLs.

Step 2 — Choose environment

Sandbox (testing)
audience: https://api-release.snapfinance.com/platform/v1
Use Sandbox while building and testing.
Production (live)
audience: https://api.snapfinance.com/platform/v1
Switch to Production when you are live.

Step 3 — Get an access token

Obtain a token and cache it on your server. The token is valid for 24 hours.

Production token endpoint https://auth.snapfinance.com/oauth/token
Sandbox token endpoint https://auth-sandbox.snapfinance.com/oauth/token

3.1 Token request fields

client_id
Client ID provided by Snap.
client_secret
Client Secret provided by Snap.
audience
Sandbox: https://api-release.snapfinance.com/platform/v1
Production: https://api.snapfinance.com/platform/v1
grant_type
Always client_credentials.

3.2 Token request (cURL)

curl --location 'https://auth-sandbox.snapfinance.com/oauth/token' \
--header 'Content-Type: application/json' \
--data '{
  "client_id": "YOUR_CLIENT_ID",
  "client_secret": "YOUR_CLIENT_SECRET",
  "audience": "https://api-release.snapfinance.com/platform/v1",
  "grant_type": "client_credentials"
}'

3.3 Token response

{
  "access_token": "eyJhbGciOi...REDACTED",
  "scope": "array of scopes",
  "expires_in": 86400,
  "token_type": "Bearer"
}

Step 4 — Add the Web SDK (v2)

4.1 Include the correct script

<!-- Sandbox (testing) -->
<script src="https://js.snapfinance.com/sandbox/v2/snap-sdk.js"></script>

<!-- Production (live) -->
<!-- <script src="https://js.snapfinance.com/v2/snap-sdk.js"></script> -->

4.2 Initialize with a server-fetched token

<script>
  // const { token } = await fetch('/api/snap/token').then(r => r.json());
  snap.init("YOUR_BEARER_TOKEN");
</script>

Step 5 — Build the transaction object

Money fields must be strings with two decimals and quantity must be an integer. Use a unique orderId each checkout.

<script>
// Example cart
const items = [
  { price: 100.00, itemId: "PROD-001", description: "Sample item 1", sku: "SKU-001", quantity: 1, leasable: true },
  { price: 50.00,  itemId: "PROD-002", description: "Sample item 2", sku: "SKU-002", quantity: 1, leasable: true }
];
const taxAmount = 8.25, shippingAmount = 12.00, discountAmount = 5.00;

function toMoney(v){ return Number(v).toFixed(2); }
function computeSubTotal(arr){ return arr.reduce((s,i)=> s + Number(i.price)*Number(i.quantity), 0); }

function buildTransaction(){
  const sub = computeSubTotal(items);
  const total = sub + taxAmount + shippingAmount - discountAmount;
  return {
    customerInformation: {
      email:"buyer@example.com", firstName:"Jane", lastName:"Doe",
      billingAddress:{ streetAddress:"123 Main St", city:"Salt Lake City", state:"UT", country:"US", postalCode:"84101", unit:"" }
    },
    cartInformation: {
      currencyCode:"USD",
      taxAmount: toMoney(taxAmount),
      shippingAmount: toMoney(shippingAmount),
      discountAmount: toMoney(discountAmount),
      totalAmount: toMoney(total),
      orderId: "ORD-" + Date.now(),
      items: items.map(i => ({
        price: toMoney(i.price), itemId: i.itemId, description: i.description, sku: i.sku,
        quantity: Number(i.quantity), leasable: Boolean(i.leasable)
      })),
      shippingAddress:{ streetAddress:"123 Main St", city:"Salt Lake City", state:"UT", country:"US", postalCode:"84101", unit:"" }
    }
  };
}
</script>

Step 6 — Render mark and button

<div id="snap-checkout-mark"></div>
<div id="snap-checkout-button"></div>
<input type="text" id="applicationId" placeholder="Application ID will appear here" />
<script>
const markMount = document.getElementById('snap-checkout-mark');
const btnMount  = document.getElementById('snap-checkout-button');

function ensureMark(){
  if (markMount.dataset.mounted === 'true' || markMount.childElementCount) return;
  snap.checkoutMark({ style:{ color:'dark', height:'40' } }).render('snap-checkout-mark');
  markMount.dataset.mounted = 'true';
}
function ensureButton(){
  if (btnMount.dataset.mounted === 'true' || btnMount.querySelector('iframe')) return;
  snap.checkoutButton({
    style:{ color:'dark', shape:'pill', height:'42' },
    onClick:(d,a)=>a.launchCheckout(buildTransaction()),
    onApproved:(d)=>{ const el=document.getElementById('applicationId'); if(d?.applicationId&&el) el.value=d.applicationId; }
  }).render('snap-checkout-button');
  btnMount.dataset.mounted = 'true';
}
ensureMark(); ensureButton();
</script>

Step 7 — Validate totals

<script>
function sumItems(arr){ return arr.reduce((s,i)=> s + Number(i.price)*Number(i.quantity), 0); }
function validateTransaction(tx){
  const ci = tx?.cartInformation; if (!ci) throw new Error('cartInformation missing');
  if (!ci.orderId) throw new Error('orderId is required');
  const computed = sumItems(ci.items) + Number(ci.taxAmount) + Number(ci.shippingAmount) - Number(ci.discountAmount);
  if (Math.abs(computed - Number(ci.totalAmount)) > 0.01) throw new Error('totalAmount mismatch');
}
</script>

Step 8 — Troubleshoot

SymptomCauseFix
Money fields rejectedNumbers sent for money fieldsSend strings with two decimals
Quantity rejectedQuantity sent as stringSend integer
“System Error”Schema mismatch or unsupported fieldRemove unsupported fields and verify totals
“Session not initialized”Render before snap.init()Initialize once, then render

Step 9 — Security best practices

  • Keep client_secret on the server only.
  • Use HTTPS for all requests.
  • Cache the token for approximately 24 hours; refresh slightly before expiry.
  • Validate and sanitize all inputs from the browser.

Step 10 — Go‑live checklist

  • Server endpoint to request and cache a token.
  • Include the correct SDK v2 script for your environment.
  • Initialize once with a valid token: snap.init(token).
  • Build a valid transaction (string money, integer quantity).
  • Render mark and button; call actions.launchCheckout(transaction) on click.
  • Handle callbacks and persist applicationId with your orderId.

Reference — Full example

<script src="https://js.snapfinance.com/sandbox/v2/snap-sdk.js"></script>
<script>
  snap.init("YOUR_BEARER_TOKEN");
  /* buildTransaction() from above */
  snap.checkoutMark({ style:{ color:"dark", height:"40" }}).render('snap-checkout-mark');
  snap.checkoutButton({
    style:{ color:"dark", shape:"pill", height:"42" },
    onClick:(d,a)=>a.launchCheckout(buildTransaction())
  }).render('snap-checkout-button');
</script>