Stripe Integration AI Prompt
Copy/paste this prompt into your AI assistant (e.g., GitHub Copilot Chat, Cursor, ChatGPT) to integrate Stripe payments with ExisOne automatic license key generation.
Prompt
You're assisting me in integrating Stripe payments with ExisOne for automatic software license key generation.
GOAL
- Integrate Stripe Checkout on my website
- When customers complete payment, Stripe sends a webhook to ExisOne
- ExisOne automatically generates a license key and emails it to the customer
- Support both one-time payments and subscription-based licensing
CONTEXT
- ExisOne webhook URL: https://www.exisone.com/api/stripe/webhook
- I have already configured my Stripe app in ExisOne with Publishable key, Secret key, and Webhook signing secret
- I have an ExisOne Product ID (found on the Products page, e.g., "42")
- The product has "Auto Email" enabled in ExisOne to send license keys automatically
HOW IT WORKS
1. My website creates a Stripe Checkout session with productId in metadata
2. Customer completes payment on Stripe Checkout
3. Stripe sends webhook to ExisOne (checkout.session.completed or invoice.paid)
4. ExisOne verifies the webhook signature matches my stored signing secret
5. ExisOne reads productId from session/subscription metadata
6. ExisOne generates license key and emails it to customer
REQUIREMENTS FOR ONE-TIME PAYMENTS
1) Server-Side: Create Checkout Session (Node.js)
const stripe = require('stripe')('sk_test_YOUR_SECRET_KEY');
app.post('/create-checkout-session', async (req, res) => {
const session = await stripe.checkout.sessions.create({
mode: 'payment',
line_items: [{
price_data: {
currency: 'usd',
unit_amount: 2999, // $29.99 in cents
product_data: {
name: 'Pro License',
},
},
quantity: 1,
}],
metadata: {
productId: '42', // ExisOne Product ID - REQUIRED
quantity: '1' // Number of licenses to generate
},
customer_email: req.body.email, // Optional: pre-fill email
success_url: 'https://yoursite.com/success',
cancel_url: 'https://yoursite.com/cancel',
});
res.json({ url: session.url });
});
2) Client-Side: Redirect to Checkout (JavaScript)
<button onclick="buyLicense()">Buy Pro License - $29.99</button>
<script>
async function buyLicense() {
const response = await fetch('/create-checkout-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: customerEmail })
});
const { url } = await response.json();
window.location.href = url; // Redirect to Stripe Checkout
}
</script>
REQUIREMENTS FOR SUBSCRIPTIONS (recurring billing)
For subscription-based licensing, ExisOne generates a NEW license key on each billing cycle.
IMPORTANT: Use subscription_data.metadata (not just metadata) for renewals to work.
1) Server-Side: Create Subscription Checkout (Node.js)
const stripe = require('stripe')('sk_test_YOUR_SECRET_KEY');
app.post('/create-subscription-checkout', async (req, res) => {
const session = await stripe.checkout.sessions.create({
mode: 'subscription',
line_items: [{
price: 'price_YOUR_RECURRING_PRICE_ID', // Created in Stripe Dashboard
quantity: 1,
}],
// IMPORTANT: Use subscription_data.metadata for renewals to work
subscription_data: {
metadata: {
productId: '42', // ExisOne Product ID - REQUIRED
quantity: '1' // Number of licenses per renewal
}
},
customer_email: req.body.email,
success_url: 'https://yoursite.com/success',
cancel_url: 'https://yoursite.com/cancel',
});
res.json({ url: session.url });
});
METADATA PLACEMENT
One-Time Payments:
| Field | Location | Required | Description |
|-----------|-----------------------------|----------|--------------------------------|
| productId | metadata.productId | Yes | ExisOne Product ID |
| quantity | metadata.quantity | No | Number of licenses (default: 1) |
Subscriptions:
| Field | Location | Required | Description |
|-----------|-----------------------------------|----------|-----------------------------------|
| productId | subscription_data.metadata.productId | Yes | Must be on subscription for renewals |
| quantity | subscription_data.metadata.quantity | No | Licenses per billing cycle |
STRIPE WEBHOOK EVENTS
- checkout.session.completed - Primary event for completed payments
- payment_intent.succeeded - Backup for one-time payments
- invoice.paid - For subscription renewals
PYTHON EXAMPLE (Flask)
import stripe
from flask import Flask, request, jsonify
stripe.api_key = 'sk_test_YOUR_SECRET_KEY'
@app.route('/create-checkout-session', methods=['POST'])
def create_checkout_session():
session = stripe.checkout.Session.create(
mode='payment',
line_items=[{
'price_data': {
'currency': 'usd',
'unit_amount': 2999,
'product_data': {'name': 'Pro License'},
},
'quantity': 1,
}],
metadata={
'productId': '42',
'quantity': '1'
},
success_url='https://yoursite.com/success',
cancel_url='https://yoursite.com/cancel',
)
return jsonify({'url': session.url})
EMAIL TEMPLATE PLACEHOLDERS
- {{ActivationKey}} - The generated license key
- {{ProductName}} - Your product name
- {{CustomerEmail}} - Customer's email address
- {{PaymentProcessorCustomerName}} - Customer name from Stripe
TESTING
1. Use test mode keys (sk_test_..., pk_test_...)
2. Use Stripe test card: 4242 4242 4242 4242 (any future expiry, any CVC)
3. Check ExisOne > Stripe Apps and Events to verify webhook received with "verified" status
4. Verify license appears in ExisOne > License Keys
5. Confirm customer received email with license key
COMMON ISSUES
Subscription renewals not generating keys:
- Ensure productId is in subscription_data.metadata, not just metadata
- The subscription object must have the metadata, not just the checkout session
- Verify webhook is listening for invoice.paid events
Signature verification fails:
- Ensure webhook signing secret (whsec_...) matches the endpoint targeting ExisOne
- Test vs Live secrets must match your mode
- Re-enter the secret in ExisOne, avoid leading/trailing spaces
GOING LIVE
1. Create new webhook endpoint in Stripe Dashboard (live mode)
2. Point to: https://www.exisone.com/api/stripe/webhook
3. Copy the live webhook signing secret
4. Add new Stripe app in ExisOne with live keys (check "Is Live")
5. Update website to use live secret key
6. Make a real test purchase (refund afterward)
DELIVERABLES
- Server-side code to create Stripe Checkout sessions with productId in metadata
- For subscriptions, use subscription_data.metadata
- Client-side redirect to Stripe Checkout
- Success/cancel page handling
- Ensure productId is always included in the appropriate metadata location
Please produce idiomatic code for my stack (Node.js/Express/Python/Flask/Django/PHP/etc. as applicable), with proper error handling and no extraneous commentary.
Notes
- See Stripe Integration Docs for complete setup guide.
- See Stripe Apps and Events to configure your Stripe app in ExisOne.
- Critical: The
metadata.productIdfield is required for license generation. - Subscriptions: Use
subscription_data.metadata(not justmetadata) for renewals to work. - Use Test Purchase page in ExisOne to verify webhook connectivity.
- Find your Product ID on the Products page.
- Enable Auto Email on your product to automatically send license keys to customers.
- Create recurring prices in Stripe Dashboard under Products > Add Product > Recurring.