Skip to content

paycan-app/paycan

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PayCan

PayCan is a self-hosted payment-integration platform. External applications use its ready-to-use web components and API to accept different payment methods in ~10 lines of code.

⭐️ Star PayCan on GitHub.
Stars are signals of support. It takes one click and makes a big difference.

Screenshots

Checkout modal (light)
Checkout modal (light)
Checkout modal (dark)
Checkout modal (dark)
Orders modal
Orders modal
Subscriptions modal
Subscriptions modal
Admin panel — Orders list
Admin panel — Orders

Click any screenshot to view it at full size.

👨‍💻 Philosophy

Payment integration shouldn't be complicated.

We believe every app should be able to collect money with just a few lines of code, without being locked into a single payment provider. PayCan's mission is to create a unified, vendor-agnostic payment integration that works seamlessly with any payment gateway while maintaining simplicity and flexibility.

No webhook handling, no customer creation, no subscription management.

  • Developer/Agent First: Minimal setup, maximum functionality

  • No Vendor Lock-in: Easily switch between payment providers

  • Unified API: One interface for all payment gateways

  • Multiple Payment Gateways: Currently supports PayPal and Stripe (Razorpay, Paddle, PayU, YooKassa, and Crypto on the roadmap)

  • Subscription and One-Time Plans: Handle recurring payments effortlessly

  • Plan Management: Dynamic subscription plan handling

Want more payment providers? ⭐️ Star the repo and, if you can, open an issue naming the provider or feature you need. Pull requests for roadmap items are always welcome

Development Notice

This application is currently under active development and is not production-ready. Please use this for learning, development, and testing purposes only. Want to contribute? We'd love your help!

🚀 Quick Start

1. Install PayCan

Follow INSTALLATION.md (web installer at /install, demo with more code snippets at /demo), then use the admin panel to create products and get your API secret key. We have two types of tokens:

Credential Header Used for
API secret key X-API-Key: <key> Admin API (server-to-server only — never expose it to browsers)
User token (JWT) Authorization: Bearer <token> User API and SDK, scoped to one user

2. Integrate Backend

Your backend exchanges the API secret key for a user-scoped token:

curl -X POST https://pay.yourapp.com/api/admin/users/sync \
  -H "X-API-Key: your_api_secret_key" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "external-user-123",
    "user": { "name": "John Doe", "email": "john@example.com" }
  }'

# → { "token": "eyJ...", "user": { ... } }

3. Integrate Frontend

The SDK lives in sdk/front/

<script type="module">
  import { PayCan, SubscriptionsModal} from 'https://paycan.yourapp.com/sdk/paycan-sdk.js';

  const paycan = new PayCan({ apiUrl: 'https://pay.yourapp.com' });

  // Token fetched from YOUR backend (which calls the users/sync endpoint above)
  const { token } = await (await fetch('/api/paycan/token')).json();
  paycan.setUserToken(token);

  // Open checkout modal for a product
  paycan.openCheckoutModal(productId, { theme: 'auto' });

  // Open subscription management modal for the user
  new SubscriptionsModal(paycan).open();

  // Or, if you prefer your own UI, get user orders directly from the API
  const orders = await paycan.orders.list();

</script>

Web Components (UI Modals)

The SDK includes five framework-agnostic modal components. They render inside a Shadow DOM (no CSS conflicts with your page), are fully responsive, and support light, dark, and auto themes.

Component Purpose Auth required
CheckoutModal Full checkout flow: price selection, gateway selection, guest email No (guest checkout is in beta)
ProductsModal Browse products/plans; opens checkout on selection; can drive plan changes No
SubscriptionsModal List, cancel, and resume the user's subscriptions Yes
OrdersModal The user's order history with downloads and licenses Yes
TransactionsModal The user's payment history Yes

Checkout and products modals (helper methods)

// Checkout for a product (user picks a price)
paycan.openCheckoutModal(productId, {
  theme: 'dark',                 // 'light' (default) | 'dark' | 'auto'
  onSuccess: (checkoutUrl) => { window.location.href = checkoutUrl; },
  onCancel: () => {},
  onError: (error) => console.error(error),
});

// Checkout for a specific price
paycan.openCheckoutModalPrice(priceId, { theme: 'light' });

// Browse products; optionally filter by type
paycan.openProductsModal({
  type: 'subscription',          // 'physical' | 'digital' | 'service' | 'subscription'
  theme: 'auto',
  onProductSelected: (product) => console.log(product),
});

Account modals (direct instantiation)

import { PayCan, SubscriptionsModal, OrdersModal, TransactionsModal }
  from 'https://pay.yourapp.com/sdk/paycan-sdk.js';

const paycan = new PayCan({ apiUrl: 'https://pay.yourapp.com' });
paycan.setUserToken(token); // required for these modals

new SubscriptionsModal(paycan, { theme: 'auto', onClose: () => {} }).open();
new OrdersModal(paycan, { theme: 'light' }).open();
new TransactionsModal(paycan, { theme: 'dark', onError: (e) => console.error(e) }).open();

Development

composer install && npm install
php artisan serve          # terminal 1
npm run dev                # terminal 2

npm run copy-sdk           # rebuild SDK and copy to public/sdk/
php artisan optimize:clear # clear caches after config/route changes
php artisan test           # run the Pest test suite
vendor/bin/pint --dirty    # code style

Security

  • Keep the API secret key on your server only; browsers must only ever receive user-scoped tokens.
  • User tokens are limited to the authenticated user's own data.
  • All public endpoints are rate-limited; webhooks are signature-verified.
  • Store secrets in .env, never in code or the database.

Found a vulnerability? Please report it privately rather than opening a public issue.

⭐️ Star PayCan on GitHub.
Stars are signals of support. It takes one click and makes a big difference.

About

Multi-gateway payment integration for your SaaS or vibe-coded app in around 10 lines of code! Think of it as an open-source alternative to Stripe Checkout but simpler to integrate and free from vendor lock-in.

Topics

Resources

Stars

15 stars

Watchers

2 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors