
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
Official TypeScript SDK for the BagelPay payment platform. Easily integrate subscription billing, one-time payments, and customer management into your TypeScript/JavaScript applications.
npm install bagelpay
import { BagelPayClient } from 'bagelpay';
async function main() {
// Initialize the client
const client = new BagelPayClient({
apiKey: 'your-api-key',
testMode: true, // Use false for production
timeout: 30000 // Optional: 30 seconds timeout
});
try {
// Create a product
const product = await client.createProduct({
name: `Premium Subscription ${Date.now()}`,
description: 'Monthly premium subscription with unique identifier',
price: 29.99,
currency: 'USD',
billingType: 'subscription',
taxInclusive: false,
taxCategory: 'digital_products',
recurringInterval: 'monthly',
trialDays: 7
});
console.log('✅ Product url:', product.productUrl);
} catch (error) {
console.error('❌ Error:', error);
}
}
// Run the main function
main().catch(console.error);
const client = new BagelPayClient({
apiKey: string, // Your BagelPay API key
testMode?: boolean, // Default: false
timeout?: number, // Default: 30000ms
baseUrl?: string // Default: https://test.bagelpay.io
});
const product = await client.createProduct({
name: string,
description: string,
price: number,
currency: string,
billingType: 'subscription' | 'single_payment',
taxInclusive: boolean,
taxCategory: string,
recurringInterval: 'daily' | 'weekly' | 'monthly' | '3months' | '6months',
trialDays: number
});
const products = await client.listProducts(page, limit);
const product = await client.getProduct(productId);
const checkout = await client.createCheckout({
productId: string,
requestId?: string,
units?: string,
customer?: { email: string },
successUrl?: string,
metadata?: Record<string, any>
});
const transactions = await client.listTransactions(page, limit);
const subscriptions = await client.listSubscriptions(page, limit);
const customers = await client.listCustomers(page, limit);
The SDK provides specific error types for better error handling:
import { BagelPayAPIError, BagelPayError } from 'bagelpay';
try {
const result = await client.createProduct(productData);
} catch (error) {
if (error instanceof BagelPayAPIError) {
console.error('API Error:', error.message);
console.error('Status Code:', error.statusCode);
} else if (error instanceof BagelPayError) {
console.error('SDK Error:', error.message);
} else {
console.error('Unknown Error:', error);
}
}
The SDK is written in TypeScript and provides full type definitions out of the box. No additional @types packages are required.
// All types are automatically inferred
const product: Product = await client.createProduct(productData);
const checkout: CheckoutResponse = await client.createCheckout(checkoutData);
Use test mode for development and testing:
const client = new BagelPayClient({
apiKey: 'bagel_test_your_test_key',
testMode: true
});
For production environments:
const client = new BagelPayClient({
apiKey: 'bagel_live_your_live_key',
testMode: false
});
import express from 'express';
import crypto from 'crypto';
import ngrok from 'ngrok';
const app = express();
const WEBHOOK_SECRET = 'your_webhook_key';
// Middleware to parse raw body for signature verification
app.use('/api/webhooks', express.raw({ type: 'application/json' }));
function verifyWebhookSignature(signatureData: Buffer, signature: string, secret: string): boolean {
/**
* Verify webhook signature for security
*/
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(signatureData)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expectedSignature, 'hex'),
Buffer.from(signature, 'hex')
);
}
app.post('/api/webhooks', async (req, res) => {
/**
* Handle BagelPay webhook notifications
*/
const payload = req.body;
const timestamp = req.headers['timestamp'] as string;
const signature = req.headers['bagelpay-signature'] as string;
// Combine payload and timestamp
const signatureData = Buffer.concat([
Buffer.from(timestamp, 'utf8'),
Buffer.from('.', 'utf8'),
payload
]);
if (!verifyWebhookSignature(signatureData, signature, WEBHOOK_SECRET)) {
return res.status(401).json({ error: 'Invalid signature' });
}
try {
const event = JSON.parse(payload.toString());
const eventType = event.event_type;
const data = event.object;
switch (eventType) {
case 'checkout.completed':
// Handle checkout completed events
console.log('Checkout completed:', event);
break;
case 'checkout.failed':
// Handle checkout failed events
console.log('Checkout failed:', event);
break;
case 'checkout.cancel':
// Handle checkout cancelled events
console.log('Checkout cancelled:', event);
break;
case 'subscription.trialing':
// Handle subscription trialing events
console.log('Subscription trialing:', event);
break;
case 'subscription.paid':
// Handle subscription paid events
console.log('Subscription paid:', event);
break;
case 'subscription.canceled':
// Handle subscription cancelled events
console.log('Subscription cancelled:', event);
break;
case 'refund.created':
// Handle refund created events
console.log('Refund created:', event);
break;
default:
console.log(`Unhandled event type: ${eventType}`);
}
return res.status(200).json({ message: 'Success' });
} catch (error) {
console.error('Webhook processing error:', error);
return res.status(500).json({ error: 'Processing failed' });
}
});
// Start server with ngrok tunnel
async function startServer() {
const listeningPort = 8000;
try {
// Set your ngrok auth token
await ngrok.authtoken('your_ngrok_key');
const publicUrl = await ngrok.connect({
addr: listeningPort,
proto: 'http',
subdomain: 'stunning-crane-direct' // Optional: use your reserved subdomain
});
console.log(`ngrok Public URL: ${publicUrl}`);
app.listen(listeningPort, '0.0.0.0', () => {
console.log(`Server running on port ${listeningPort}`);
});
} catch (error) {
console.error('Failed to start server:', error);
}
}
if (require.main === module) {
startServer();
}
MIT License - see LICENSE file for details.
We welcome contributions! Please see our Contributing Guide for details.
Ready to get started? Sign up for a BagelPay account and get your API keys today!
FAQs
TypeScript SDK for BagelPay API
The npm package bagelpay receives a total of 78 weekly downloads. As such, bagelpay popularity was classified as not popular.
We found that bagelpay demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.