Skip to main content

JavaScript/Node.js Examples

Complete JavaScript client for Ozura Vault.

Installation

No SDK required - uses native fetch API. For Node.js < 18, install node-fetch:
npm install node-fetch

Complete Client Library

// ozura-vault-client.js

class OzuraVaultClient {
  constructor(apiKey, baseUrl = 'https://pci-vault-hrhwdgc4akhse3bs.eastus-01.azurewebsites.net') {
    this.apiKey = apiKey;
    this.baseUrl = baseUrl;
  }

  async request(endpoint, options = {}) {
    const url = `${this.baseUrl}${endpoint}`;
    const headers = {
      'Content-Type': 'application/json',
      'X-API-Key': this.apiKey,
      ...options.headers
    };

    const response = await fetch(url, {
      ...options,
      headers
    });

    const data = await response.json();

    if (!data.success) {
      const error = new Error(data.message);
      error.response = data;
      throw error;
    }

    return data;
  }

  // Tokenization
  async tokenize(type, cardData) {
    return this.request('/tokenize', {
      method: 'POST',
      body: JSON.stringify({ type, data: cardData })
    });
  }

  async tokenizeCard(cardNumber, expirationMonth, expirationYear, cvv = null) {
    const data = { cardNumber, expirationMonth, expirationYear };
    if (cvv) data.cvv = cvv;
    return this.tokenize('card', data);
  }

  async tokenizeBank(accountNumber, routingNumber, accountType) {
    return this.tokenize('bank', { accountNumber, routingNumber, accountType });
  }

  async createTestToken(cardData) {
    return this.request('/test-tokens', {
      method: 'POST',
      body: JSON.stringify({ type: 'card', data: cardData })
    });
  }

  // Detokenization
  async detokenize(token) {
    return this.request('/detokenize', {
      method: 'POST',
      body: JSON.stringify({ token })
    });
  }

  // Proxy
  async proxy(token, cvcSessionId, proxyUrl, requestData, httpHeaders = {}) {
    return this.request('/proxy/transaction', {
      method: 'POST',
      body: JSON.stringify({
        token,
        cvc_session_id: cvcSessionId,
        proxy_url: proxyUrl,
        request_data: requestData,
        http_headers: httpHeaders
      })
    });
  }

  // Verify API Key
  async verifyApiKey() {
    return this.request('/api/applications/key', {
      method: 'GET'
    });
  }
}

module.exports = OzuraVaultClient;

Usage Examples

Initialize Client

const OzuraVaultClient = require('./ozura-vault-client');

const client = new OzuraVaultClient(process.env.OZURA_API_KEY);

Tokenize a Card

async function tokenizeCard() {
  try {
    const result = await client.tokenizeCard(
      '4111111111111111',
      '12',
      '2025',
      '123'
    );

    console.log('Token:', result.token);
    console.log('CVC Session:', result.cvc_session_id);
    console.log('Masked:', result.mask.card_number);

    return result;
  } catch (error) {
    console.error('Tokenization failed:', error.message);
    throw error;
  }
}

Process Payment with Stripe

async function processStripePayment(token, cvcSessionId, amount) {
  try {
    const result = await client.proxy(
      token,
      cvcSessionId,
      'https://api.stripe.com/v1/charges',
      {
        amount: amount,
        currency: 'usd',
        source: {
          object: 'card',
          number: '${cardNumber}',
          exp_month: '${expirationMonth}',
          exp_year: '${expirationYear}',
          cvc: '${cvv}'
        }
      },
      {
        'Authorization': `Bearer ${process.env.STRIPE_SECRET_KEY}`
      }
    );

    const stripeResponse = result.proxy_response.body;
    console.log('Charge ID:', stripeResponse.id);
    console.log('Status:', stripeResponse.status);

    return stripeResponse;
  } catch (error) {
    console.error('Payment failed:', error.message);
    throw error;
  }
}

Complete Checkout Flow

async function checkout(cardDetails, amount) {
  // 1. Tokenize the card
  const tokenResult = await client.tokenizeCard(
    cardDetails.number,
    cardDetails.expMonth,
    cardDetails.expYear,
    cardDetails.cvv
  );

  // 2. Store token for future use
  await saveToDatabase({
    customerId: cardDetails.customerId,
    token: tokenResult.token,
    last4: tokenResult.mask.card_number.slice(-4)
  });

  // 3. Process payment
  const payment = await processStripePayment(
    tokenResult.token,
    tokenResult.cvc_session_id,
    amount
  );

  return payment;
}

Express.js Integration

const express = require('express');
const OzuraVaultClient = require('./ozura-vault-client');

const app = express();
const vault = new OzuraVaultClient(process.env.OZURA_API_KEY);

app.use(express.json());

// Tokenize endpoint
app.post('/api/tokenize', async (req, res) => {
  try {
    const { cardNumber, expMonth, expYear, cvv } = req.body;

    const result = await vault.tokenizeCard(
      cardNumber,
      expMonth,
      expYear,
      cvv
    );

    res.json({
      token: result.token,
      cvcSessionId: result.cvc_session_id,
      last4: result.mask.card_number.slice(-4)
    });
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
});

// Payment endpoint
app.post('/api/pay', async (req, res) => {
  try {
    const { token, cvcSessionId, amount } = req.body;

    const result = await vault.proxy(
      token,
      cvcSessionId,
      'https://api.stripe.com/v1/charges',
      {
        amount,
        currency: 'usd',
        source: {
          object: 'card',
          number: '${cardNumber}',
          exp_month: '${expirationMonth}',
          exp_year: '${expirationYear}',
          cvc: '${cvv}'
        }
      },
      {
        'Authorization': `Bearer ${process.env.STRIPE_SECRET_KEY}`
      }
    );

    if (result.proxy_response.status_code >= 400) {
      throw new Error(result.proxy_response.body.error?.message || 'Payment failed');
    }

    res.json(result.proxy_response.body);
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
});

app.listen(3000, () => console.log('Server running on port 3000'));

Error Handling

async function safeTokenize(cardData) {
  try {
    return await client.tokenizeCard(
      cardData.number,
      cardData.expMonth,
      cardData.expYear,
      cardData.cvv
    );
  } catch (error) {
    switch (error.message) {
      case 'Invalid API key':
        // Handle auth error
        console.error('Check your API key configuration');
        break;
      case 'Invalid card number':
        // Handle validation error
        console.error('Please check the card number');
        break;
      default:
        console.error('Unexpected error:', error.message);
    }
    throw error;
  }
}

Next Steps