Skip to content

Instantly share code, notes, and snippets.

@acomagu
Last active November 7, 2025 10:14
Show Gist options
  • Select an option

  • Save acomagu/fc473bcd1a7ddce002a210fe10b89e2e to your computer and use it in GitHub Desktop.

Select an option

Save acomagu/fc473bcd1a7ddce002a210fe10b89e2e to your computer and use it in GitHub Desktop.
import * as restate from "@restatedev/restate-sdk";
import { serde } from "@restatedev/restate-sdk-zod";
import { Stripe } from 'stripe';
const stripe = new Stripe('STRIPE_KEY');
const apiHandler = restate.service({
name: "APIHandler",
handlers: {
async onStripeEvent(ctx, event: Stripe.Event) {
if (event.type === 'checkout.session.completed') {
const purchaseId = event.data.object.client_reference_id;
if (!purchaseId) return;
ctx.workflowSendClient(purchaseWorkflow, purchaseId).onPaymentSucceeded();
} else if (event.type === 'checkout.session.expired') {
const purchaseId = event.data.object.client_reference_id;
if (!purchaseId) return;
ctx.workflowSendClient(purchaseWorkflow, purchaseId).onPaymentExpired();
}
},
async createCheckoutSession(ctx) {
const purchaseId = ctx.rand.uuidv4();
const stripeCheckoutSession = await ctx.run('Checkout Session 作成', () => {
return stripe.checkout.sessions.create({
line_items: [{
quantity: 1,
price_data: {
currency: 'JPY',
unit_amount: 100,
product_data: {
name: '商品',
},
},
}],
success_url: 'http://example.com',
mode: 'payment',
client_reference_id: purchaseId,
});
});
ctx.workflowClient(purchaseWorkflow, purchaseId).run();
return stripeCheckoutSession.url;
},
},
});
const purchaseWorkflow = restate.workflow({
name: 'Purchase',
handlers: {
async run(ctx) {
console.log('商品確保');
const paymentSucceeded = await ctx.promise<boolean>('paymentSucceeded');
if (!paymentSucceeded) {
console.log('商品解放');
return;
}
console.log('商品購入完了');
await ctx.run(() => {
console.log('メール送信');
});
},
async onPaymentSucceeded(ctx: restate.WorkflowSharedContext) {
await ctx.promise<boolean>('paymentSucceeded').resolve(true);
},
async onPaymentExpired(ctx: restate.WorkflowSharedContext) {
await ctx.promise<boolean>('paymentSucceeded').resolve(false);
},
},
});
restate.serve({
services: [apiHandler, purchaseWorkflow],
port: 9080,
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment