npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@one-payments/adapters-web

v1.0.6

Published

Web platform adapters for One Payments SDK

Readme

@one-payments/adapters-web

Web platform adapters for One Payments SDK. Provides browser-based implementations for HTTP, Storage, Crypto, and Timer operations.

Features

  • 🌐 Browser APIs - Built on native Web APIs (Fetch, LocalStorage, Web Crypto, setTimeout)
  • 🔒 Secure - Uses Web Crypto API for HMAC generation
  • 💾 Persistent Storage - LocalStorage for session management
  • Lightweight - No external dependencies
  • 🎯 TypeScript - Full type safety
  • 🧩 Framework Agnostic - Works with React, Vue, Angular, and vanilla JS

Installation

npm install @one-payments/adapters-web
# or
yarn add @one-payments/adapters-web
# or
pnpm add @one-payments/adapters-web

Usage

Basic Usage

import { createWebAdapters } from '@one-payments/adapters-web';

// Create adapters instance
const adapters = createWebAdapters();

// Use with any One Payments component
// React example:
<OnePayment
  config={config}
  adapters={adapters}
  amount={5000}
  currency="USD"
  orderId="order-123"
/>

React

import { createWebAdapters } from '@one-payments/adapters-web';
import { OnePayment } from '@one-payments/react';

function CheckoutPage() {
  const adapters = createWebAdapters();

  return (
    <OnePayment
      config={config}
      adapters={adapters}
      {...paymentProps}
    />
  );
}

Vue 3

<script setup lang="ts">
import { createWebAdapters } from '@one-payments/adapters-web';
import { OnePayment } from '@one-payments/vue';

const adapters = createWebAdapters();
</script>

<template>
  <OnePayment
    :config="config"
    :adapters="adapters"
    v-bind="paymentProps"
  />
</template>

Angular

import { Component } from '@angular/core';
import { createWebAdapters } from '@one-payments/adapters-web';
import { OnePaymentComponent } from '@one-payments/angular';

@Component({
  selector: 'app-checkout',
  standalone: true,
  imports: [OnePaymentComponent],
  template: `
    <one-payment
      [config]="config"
      [adapters]="adapters"
    />
  `
})
export class CheckoutComponent {
  adapters = createWebAdapters();
}

Vanilla JavaScript

<!DOCTYPE html>
<html>
<head>
  <script type="module" src="https://unpkg.com/@one-payments/web-components"></script>
</head>
<body>
  <one-payment id="payment"></one-payment>

  <script type="module">
    import { createWebAdapters } from 'https://unpkg.com/@one-payments/adapters-web';

    const adapters = createWebAdapters();
    const paymentElement = document.getElementById('payment');

    paymentElement.adapters = adapters;
    paymentElement.config = { /*...*/ };
  </script>
</body>
</html>

Server-Side Rendering (SSR)

Important: This package uses browser-only APIs and cannot be used during server-side rendering. Initialize adapters on the client-side only.

Next.js Integration

For Next.js (and other SSR frameworks), dynamically import and initialize adapters in useEffect:

'use client';

import { useState, useEffect } from 'react';
import dynamic from 'next/dynamic';
import type { Adapters } from '@one-payments/core';

// Dynamic import of payment component
const OnePayment = dynamic(
  () => import('@one-payments/react').then((mod) => mod.OnePayment),
  { ssr: false }
);

export default function CheckoutPage() {
  const [adapters, setAdapters] = useState<Adapters | null>(null);

  // Initialize adapters on client-side only
  useEffect(() => {
    import('@one-payments/adapters-web').then(({ createWebAdapters }) => {
      setAdapters(createWebAdapters());
    });
  }, []);

  if (!adapters) {
    return <div>Loading payment system...</div>;
  }

  return (
    <OnePayment
      config={config}
      adapters={adapters}
      {...props}
    />
  );
}

Why this is needed:

  • Web APIs like window, localStorage, crypto.subtle don't exist in Node.js
  • SSR renders on the server first, causing "ReferenceError: window is not defined"
  • Dynamic import with ssr: false ensures code only runs in the browser

See the Next.js Integration Guide for complete instructions.

Nuxt 3

<script setup>
import { ref, onMounted } from 'vue';

const adapters = ref(null);

onMounted(async () => {
  const { createWebAdapters } = await import('@one-payments/adapters-web');
  adapters.value = createWebAdapters();
});
</script>

<template>
  <ClientOnly>
    <OnePayment v-if="adapters" :adapters="adapters" />
  </ClientOnly>
</template>

Adapter Implementations

HTTP Adapter

Uses the native fetch API for HTTP requests:

interface HttpAdapter {
  fetch(url: string, options?: RequestInit): Promise<Response>;
}

// Implementation
const httpAdapter = {
  fetch: (url, options) => window.fetch(url, options)
};

Storage Adapter

Uses localStorage for persistent client-side storage:

interface StorageAdapter {
  getItem(key: string): Promise<string | null>;
  setItem(key: string, value: string): Promise<void>;
  removeItem(key: string): Promise<void>;
}

// Implementation
const storageAdapter = {
  getItem: (key) => Promise.resolve(localStorage.getItem(key)),
  setItem: (key, value) => Promise.resolve(localStorage.setItem(key, value)),
  removeItem: (key) => Promise.resolve(localStorage.removeItem(key))
};

Storage Keys Used:

  • one-payments-session-* - Payment session data
  • one-payments-config-* - Cached configuration

Crypto Adapter

Uses Web Crypto API for secure cryptographic operations:

interface CryptoAdapter {
  generateHMAC(message: string, secret: string): Promise<string>;
  randomUUID(): string;
}

// Implementation uses crypto.subtle for HMAC-SHA256
const cryptoAdapter = {
  generateHMAC: async (message, secret) => {
    const encoder = new TextEncoder();
    const keyData = encoder.encode(secret);
    const messageData = encoder.encode(message);

    const key = await crypto.subtle.importKey(
      'raw',
      keyData,
      { name: 'HMAC', hash: 'SHA-256' },
      false,
      ['sign']
    );

    const signature = await crypto.subtle.sign('HMAC', key, messageData);
    return Array.from(new Uint8Array(signature))
      .map(b => b.toString(16).padStart(2, '0'))
      .join('');
  },
  randomUUID: () => crypto.randomUUID()
};

Timer Adapter

Uses native JavaScript timer functions:

interface TimerAdapter {
  setTimeout(callback: () => void, delay: number): number;
  clearTimeout(id: number): void;
}

// Implementation
const timerAdapter = {
  setTimeout: (callback, delay) => window.setTimeout(callback, delay),
  clearTimeout: (id) => window.clearTimeout(id)
};

Browser Support

Required Browser Features

  • Fetch API - All modern browsers (IE11 needs polyfill)
  • LocalStorage - All browsers supporting Web Storage API
  • Web Crypto API - Chrome 37+, Firefox 34+, Safari 11+, Edge 12+
  • crypto.randomUUID() - Chrome 92+, Firefox 95+, Safari 15.4+

Polyfills

For older browsers, you may need polyfills:

<!-- Fetch polyfill for IE11 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/fetch.umd.js"></script>

<!-- crypto.randomUUID polyfill -->
<script>
if (!crypto.randomUUID) {
  crypto.randomUUID = function() {
    return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
      (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
    );
  };
}
</script>

Browser Compatibility

| Browser | Minimum Version | Notes | |---------|----------------|-------| | Chrome | 92+ | Full support | | Firefox | 95+ | Full support | | Safari | 15.4+ | Full support | | Edge | 92+ | Full support | | Mobile Safari | iOS 15.4+ | Full support | | Chrome Mobile | 92+ | Full support |

Security Considerations

HMAC Generation

  • Uses Web Crypto API's crypto.subtle for secure HMAC-SHA256
  • Secret keys never leave the browser
  • HMAC signatures used for API request authentication

Storage Security

  • Uses localStorage which is origin-isolated
  • Data is accessible only to your domain
  • No sensitive card data is stored (PCI compliance)
  • Session tokens expire after use

Content Security Policy (CSP)

If your site uses CSP, ensure these directives:

Content-Security-Policy:
  script-src 'self' 'unsafe-eval';
  connect-src 'self' https://*.one.ooo;
  frame-src https://*.one.ooo;

Comparison with Other Adapters

vs. @one-payments/adapters-crypto-js

| Feature | adapters-web | adapters-crypto-js | |---------|--------------|-------------------| | Environment | Modern browsers | Legacy browsers, WebView | | Crypto | Web Crypto API | CryptoJS library | | Bundle Size | ~2KB | ~50KB | | Performance | Native (faster) | JavaScript (slower) | | Use Case | Standard web apps | React Native WebView, IE11 |

Use @one-payments/adapters-crypto-js when:

  • Supporting IE11 or older browsers
  • Using React Native WebView (no Web Crypto API)
  • Server-side rendering with crypto operations

Use @one-payments/adapters-web when:

  • Building modern web applications
  • Supporting Chrome, Firefox, Safari, Edge (latest versions)
  • Performance is a priority

vs. @one-payments/adapters-native

| Feature | adapters-web | adapters-native | |---------|--------------|-----------------| | Platform | Web browsers | React Native | | Storage | localStorage | AsyncStorage | | HTTP | fetch | React Native fetch | | Use Case | Web apps | Native mobile apps |

Troubleshooting

Error: "window is not defined"

Cause: Trying to import adapters during SSR

Solution: Initialize in useEffect (React) or onMounted (Vue):

// ❌ Don't do this
const adapters = createWebAdapters();

// ✅ Do this
const [adapters, setAdapters] = useState(null);
useEffect(() => {
  import('@one-payments/adapters-web').then(({ createWebAdapters }) => {
    setAdapters(createWebAdapters());
  });
}, []);

Error: "crypto.subtle is undefined"

Cause: Page not served over HTTPS (Web Crypto requires secure context)

Solution:

  • Use HTTPS in production
  • For localhost, modern browsers allow HTTP
  • For testing, use chrome://flags/#unsafely-treat-insecure-origin-as-secure

Error: "localStorage is not defined"

Cause: Browser privacy mode or storage disabled

Solution: Check if storage is available:

try {
  const adapters = createWebAdapters();
} catch (error) {
  console.error('Storage not available:', error);
  // Show message to user to disable privacy mode
}

Testing

Mock adapters in tests:

// test-utils.ts
export const mockAdapters = {
  http: {
    fetch: jest.fn()
  },
  storage: {
    getItem: jest.fn(),
    setItem: jest.fn(),
    removeItem: jest.fn()
  },
  crypto: {
    generateHMAC: jest.fn().mockResolvedValue('mock-hmac'),
    randomUUID: jest.fn().mockReturnValue('mock-uuid')
  },
  timer: {
    setTimeout: jest.fn(),
    clearTimeout: jest.fn()
  }
};

// Your test
it('should process payment', () => {
  render(<OnePayment adapters={mockAdapters} {...props} />);
  // ...
});

Related Packages

Requirements

  • Modern browser with ES2020 support
  • HTTPS (for Web Crypto API)
  • LocalStorage enabled

Bundle Size

  • Minified: ~2KB
  • Gzipped: ~1KB

License

MIT