Skip to main content

First Integration

Complete end-to-end integration example with code samples.

Overview

This guide walks through building a complete subscription integration, from initial setup to handling webhooks.

Project Setup

1. Install Dependencies

# Node.js/JavaScript
npm install @azotte/sdk

# Python
pip install azotte-python

# .NET
dotnet add package Azotte.SDK

2. Initialize SDK

// JavaScript/Node.js
import { AzotteClient } from '@azotte/sdk';

const azotte = new AzotteClient({
apiKey: process.env.AZOTTE_API_KEY,
tenantId: process.env.AZOTTE_TENANT_ID,
environment: 'sandbox' // or 'production'
});
# Python
from azotte import AzotteClient

azotte = AzotteClient(
api_key=os.environ['AZOTTE_API_KEY'],
tenant_id=os.environ['AZOTTE_TENANT_ID'],
environment='sandbox'
)
// C#/.NET
using Azotte.SDK;

var azotte = new AzotteClient(new AzotteClientOptions
{
ApiKey = Environment.GetEnvironmentVariable("AZOTTE_API_KEY"),
TenantId = Environment.GetEnvironmentVariable("AZOTTE_TENANT_ID"),
Environment = AzotteEnvironment.Sandbox
});

Complete Integration Flow

1. Customer Registration

// Create customer
const customer = await azotte.customers.create({
email: 'customer@example.com',
name: 'John Doe',
metadata: {
source: 'web_signup'
}
});

2. Subscription Creation

// Create subscription
const subscription = await azotte.subscriptions.create({
customerId: customer.id,
priceId: 'price_premium_monthly',
paymentMethodId: 'pm_card_visa',
startDate: new Date().toISOString()
});

3. Handle Payment

// Process initial payment
const payment = await azotte.payments.create({
subscriptionId: subscription.id,
amount: subscription.price.amount,
currency: subscription.price.currency,
paymentMethodId: subscription.paymentMethodId
});

if (payment.status === 'succeeded') {
console.log('Payment successful, subscription activated');
} else {
console.log('Payment failed:', payment.failureReason);
}

4. Webhook Integration

// Express.js webhook handler
app.post('/webhooks/azotte', express.raw({type: 'application/json'}), (req, res) => {
const sig = req.headers['azotte-signature'];

try {
const event = azotte.webhooks.constructEvent(
req.body,
sig,
process.env.AZOTTE_WEBHOOK_SECRET
);

switch (event.type) {
case 'subscription.created':
handleSubscriptionCreated(event.data);
break;
case 'subscription.canceled':
handleSubscriptionCanceled(event.data);
break;
case 'payment.succeeded':
handlePaymentSucceeded(event.data);
break;
case 'payment.failed':
handlePaymentFailed(event.data);
break;
}

res.json({received: true});
} catch (err) {
console.log('Webhook signature verification failed:', err.message);
res.status(400).send(`Webhook Error: ${err.message}`);
}
});

Frontend Integration

React Component Example

import React, { useState } from 'react';
import { AzotteCheckout } from '@azotte/react';

function SubscriptionPage() {
const [loading, setLoading] = useState(false);

const handleSubscription = async (priceId) => {
setLoading(true);

try {
const result = await AzotteCheckout.open({
priceId: priceId,
customerId: currentUser.id,
successUrl: '/success',
cancelUrl: '/cancel'
});

if (result.success) {
// Redirect to success page or show confirmation
window.location.href = '/subscription/success';
}
} catch (error) {
console.error('Subscription failed:', error);
} finally {
setLoading(false);
}
};

return (
<div>
<h1>Choose Your Plan</h1>
<div className="pricing-cards">
<div className="card">
<h3>Basic Plan</h3>
<p>$9.99/month</p>
<button
onClick={() => handleSubscription('price_basic_monthly')}
disabled={loading}
>
Subscribe
</button>
</div>
<div className="card">
<h3>Premium Plan</h3>
<p>$19.99/month</p>
<button
onClick={() => handleSubscription('price_premium_monthly')}
disabled={loading}
>
Subscribe
</button>
</div>
</div>
</div>
);
}

Testing Your Integration

1. Test with Sample Data

// Use test mode data
const testCustomer = await azotte.customers.create({
email: 'test@example.com',
name: 'Test User'
});

// Use test payment methods
const testPayment = await azotte.paymentMethods.create({
type: 'card',
card: {
number: '4242424242424242', // Test card number
expMonth: 12,
expYear: 2025,
cvc: '123'
}
});

2. Monitor Events

// Check subscription status
const subscription = await azotte.subscriptions.retrieve(subscriptionId);
console.log('Subscription status:', subscription.status);

// List recent payments
const payments = await azotte.payments.list({
subscriptionId: subscriptionId,
limit: 10
});

Error Handling

try {
const subscription = await azotte.subscriptions.create(subscriptionData);
} catch (error) {
if (error.code === 'payment_method_declined') {
// Handle declined payment
showError('Payment method was declined. Please try a different card.');
} else if (error.code === 'subscription_limit_exceeded') {
// Handle subscription limits
showError('Subscription limit reached. Please contact support.');
} else {
// Handle other errors
console.error('Unexpected error:', error);
showError('Something went wrong. Please try again.');
}
}

Next Steps