From 66604ff571c8aadd46445951851cbe57ae87eab1 Mon Sep 17 00:00:00 2001 From: marcus-sa <8391194+marcus-sa@users.noreply.github.com> Date: Sat, 24 Aug 2024 21:33:18 +0200 Subject: [PATCH] improvements --- bun.lockb | Bin 419440 -> 419912 bytes common/src/lib/entities.ts | 4 + common/src/lib/errors.ts | 3 + common/src/lib/repository.ts | 2 +- common/src/lib/types.ts | 2 + customer-service-api/src/lib/entities.ts | 18 ++- customer-service-api/src/lib/events.ts | 11 +- delivery-service-api/src/lib/services.ts | 5 +- kitchen-service-api/src/lib/entities.ts | 11 ++ kitchen-service/src/kitchen.service.ts | 4 +- order-service-api/src/lib/replies.ts | 8 ++ order-service-api/src/lib/sagas.ts | 7 +- order-service-api/src/lib/services.ts | 11 +- order-service/src/order.service.ts | 2 +- order-service/src/sagas/create-order.saga.ts | 54 +++++---- package.json | 1 + payment-service-api/src/lib/entities.ts | 49 +++++++- payment-service-api/src/lib/replies.ts | 18 ++- payment-service-api/src/lib/services.ts | 14 +-- payment-service/src/config.ts | 10 +- payment-service/src/main.ts | 11 +- payment-service/src/payment.repository.ts | 17 ++- payment-service/src/payment.service.ts | 106 ++++++++++++++++-- .../src/stripe-customer.repository.ts | 20 ++++ payment-service/src/stripe.ts | 13 +++ payment-service/src/types.ts | 13 +++ 26 files changed, 345 insertions(+), 69 deletions(-) create mode 100644 payment-service/src/stripe-customer.repository.ts create mode 100644 payment-service/src/stripe.ts create mode 100644 payment-service/src/types.ts diff --git a/bun.lockb b/bun.lockb index 58f863fc153142c5c0727a8121b7edda668b3c2b..30087d615ae8d6207b2294ee1e777aeece614bad 100755 GIT binary patch delta 83535 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

CT?r+eHzHT7A z(l!6hSM?da_~S0*B87~?OI0Pw^G&<@%Z93%xr(YNbE8?+W*M6EfU_RHM9K0#pUHpG z`kA{7U-DDXwrV%NqRQH8&0m+fHGvxMwMDh6c53`vUKsBzKLoHwgSh4;V+)Ko|CrFe zE@Wd)w_beQtvK3IEhpZWMRYrTHWF9V=j|e z`5(j5`OWQqeHUNfq)!oFzczR3ouO>aQ)`i{N6oylr?&q4F5VTFg#O#!y)N+8-n}#K zeVx|o)CUq9wf6gJ{iZ@cqBWVN7_)5j7vPNsXpO|*EE}tNMU4dQR9A}3s#vw}Epb#- zJ3nbNojHox^;ZQN|M}^0zcER!yV{W1(gTXAai1B}z8>-{Wz-0nwVZT!!ql6cF|0ZY z6;n;W;L{o%W3?lxM|J%Ri814{;`l1#4zHtATe???YH6n4H@~V1zw#pI0^ z8oxB-4O2hS3QT3@o(iyYXKr;gx4UcRyK(X4sb-=QD$?$rCd99VU4MtF=x+&f)J||{ zvrFR*#U(WjBHhGFU0ThX{DaG7fwD_$iypFRHB~uraSkbIc&(Y;KlA1pjeJ}wG#hGE z6EHeNe7!^P-oqS+dm6i*3x{6`b=KiN!&=!mmzA>XKfE9K;@mz?SJ^0G8Y`9UYQ7uE znXa~DIL{y_yVt3@=e{{{bCL|miO#_4aGiRNKuF93Xn93Mey4*z{0|e1cx`*B_=dW9 z!~XQNKO!(u6Go__ntPD(@@iE_(K2d}M%gtiBj3!kMV6ZOLx)SVU$uAG<>g5_ku4mT zgt+AWuYZf2vBr#8wY+?Bl~d*7xmU>>cf8+`wL|-tE)#4rF@C4LP zeKj)y>FHe2SktbrSfD|b&=A_R^;YWubqYD(WR(mBSQ9ZN?~rQ&Eyx+<2bl1iVD zJm*6~Ug4YjbLiiT&gYOmW;T*4s%Ao3+ZDApF%^LP)x=alrpjs_{z5`38&iyDpYH3I zl+D0(;cST&?V(N21@^_Hur##^0Eo6$& zrtVW+c^Fp1=-~S=lzB4ve*Y}E$V!Pxt_(d&0=G`a_OvTxW!EC^!(Z#xG^*Hp?Tx@Z ztG*O4n-C5pray>t4{=7>~?LV(lczjsK!(rDyw`c*nonzn7c}z_NT~7mOMS($p$}JPp;}Db1$Q& zC36q7*HK53xo2=>=%yYeb5HNc(M=`ta8I9ccwb`|;qXrzKJKqkbIDZhWdrX{uOaO{ zTUWd?S5@?I&yexuVPj!_XkU@AqWP1~kNG;`OEn6yh--Z5PZldvx1?K_YQ(y%56t_% zzii1-^Z1L4e{nAfNVVm}KQx!eki-*_gYP>`;EG*=>y-%{wOK4CMPPyJm>n~s0H*^R0G8Ggl zXCE+pgXgjH+^68afP31dqjt8b^pJa*90R6TSdj7KiQ%HGbZ)Rmd&qIo3_2$b?w^GZ)-*`_i+y8cfj4Qfe zUMAH%Bwjq_-_(83){%MLdum(Pdb?lp+4>>CJt)tJjZNLRZfqLwZ^zatE#gJGB~BA= z#OWIzPpwU;WhC9U@6%41*R5o)((TH&E>pvFZxF8PwTYK2(LD2hTe$kEO}t``!gbWq IHu0AHe}M!xQ2+n{ delta 83255 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 q`CaMuWm}i&V|qrlQ334| { .findOneOrUndefined(); } - async persist(entity: E): Promise { + async save(entity: E): Promise { await this.#ctx.run(() => this.database.persist(entity)); } diff --git a/common/src/lib/types.ts b/common/src/lib/types.ts index a62ff82..c0fefb1 100644 --- a/common/src/lib/types.ts +++ b/common/src/lib/types.ts @@ -1,3 +1,5 @@ +import { Unique } from '@deepkit/type'; + export interface PersonName { readonly firstName: string; readonly lastName: string; diff --git a/customer-service-api/src/lib/entities.ts b/customer-service-api/src/lib/entities.ts index 7eb050f..d8db2d0 100644 --- a/customer-service-api/src/lib/entities.ts +++ b/customer-service-api/src/lib/entities.ts @@ -1,4 +1,12 @@ -import { entity, PrimaryKey, uuid, UUID } from '@deepkit/type'; +import { + Email, + entity, + JSONPartial, + PrimaryKey, + Unique, + uuid, + UUID, +} from '@deepkit/type'; import { Writable } from 'type-fest'; import { PersonName } from '@ftgo/common'; @@ -10,7 +18,13 @@ export class Customer { readonly id: UUID & PrimaryKey = uuid(); readonly disabled: boolean = false; - constructor(readonly name: PersonName) {} + readonly name: PersonName; + readonly email: Email & Unique; + readonly phoneNumber?: string & Unique; + + static create(data: JSONPartial) { + return Object.assign(new Customer(), data); + } assertEnabled(): void { if (!this.disabled) { diff --git a/customer-service-api/src/lib/events.ts b/customer-service-api/src/lib/events.ts index 45c1536..3f70b73 100644 --- a/customer-service-api/src/lib/events.ts +++ b/customer-service-api/src/lib/events.ts @@ -1,5 +1,12 @@ -import { Customer } from './entities'; +import { Email, UUID } from '@deepkit/type'; + +import { PersonName } from '@ftgo/common'; export class CustomerCreatedEvent { - constructor(readonly customer: Customer) {} + constructor( + readonly id: UUID, + readonly name: PersonName, + readonly email: Email, + readonly phoneNumber?: string, + ) {} } diff --git a/delivery-service-api/src/lib/services.ts b/delivery-service-api/src/lib/services.ts index 8e4d7e0..48f27fd 100644 --- a/delivery-service-api/src/lib/services.ts +++ b/delivery-service-api/src/lib/services.ts @@ -1,7 +1,4 @@ -import { RestateClient, RestateService } from 'deepkit-restate'; -import { typeOf, UUID } from '@deepkit/type'; - -import { FactoryProvider } from '@deepkit/injector'; +import { RestateService } from 'deepkit-restate'; export interface DeliveryServiceHandlers {} diff --git a/kitchen-service-api/src/lib/entities.ts b/kitchen-service-api/src/lib/entities.ts index 18cc1da..f826d39 100644 --- a/kitchen-service-api/src/lib/entities.ts +++ b/kitchen-service-api/src/lib/entities.ts @@ -1,6 +1,8 @@ import { entity, integer, JSONEntity, Positive, UUID } from '@deepkit/type'; import { Writable } from 'type-fest'; +import { UnsupportedStateTransitionException } from '@ftgo/common'; + @entity.name('kitchen') export class Kitchen { static create(data: JSONEntity): Kitchen { @@ -35,11 +37,20 @@ export class Ticket { } cancel(this: Writable) { + if ( + this.state !== TicketState.CREATED && + this.state !== TicketState.CONFIRMED + ) { + throw new UnsupportedStateTransitionException(this.state); + } this.state = TicketState.CANCELLED; // delete this.confirmCancelAwakeableId; } confirm(this: Writable): void { + if (this.state !== TicketState.CREATED) { + throw new UnsupportedStateTransitionException(this.state); + } this.state = TicketState.CONFIRMED; // delete this.confirmCreateAwakeableId; } diff --git a/kitchen-service/src/kitchen.service.ts b/kitchen-service/src/kitchen.service.ts index f1db3d6..318ceec 100644 --- a/kitchen-service/src/kitchen.service.ts +++ b/kitchen-service/src/kitchen.service.ts @@ -38,7 +38,7 @@ export class KitchenService implements KitchenServiceHandlers { throw new TicketNotFound(id); } ticket.cancel(); - await this.ticket.persist(ticket); + await this.ticket.save(ticket); await this.ctx.rejectAwakeable( ticket.confirmCreateAwakeableId!, CreateOrderSagaState.CANCELLED, @@ -59,7 +59,7 @@ export class KitchenService implements KitchenServiceHandlers { throw new TicketNotFound(id); } ticket.confirm(); - await this.ticket.persist(ticket); + await this.ticket.save(ticket); await this.ctx.resolveAwakeable( ticket.confirmCreateAwakeableId!, new TicketConfirmed(readyAt), diff --git a/order-service-api/src/lib/replies.ts b/order-service-api/src/lib/replies.ts index 4a5988f..3053e38 100644 --- a/order-service-api/src/lib/replies.ts +++ b/order-service-api/src/lib/replies.ts @@ -12,6 +12,14 @@ export class OrderNotFound extends Error { } } +export class OrderApproved { + constructor() {} +} + +export class OrderRejected { + constructor() {} +} + export class OrderRevisionProposed { constructor( readonly revision: OrderRevision, diff --git a/order-service-api/src/lib/sagas.ts b/order-service-api/src/lib/sagas.ts index 67af054..c85cbec 100644 --- a/order-service-api/src/lib/sagas.ts +++ b/order-service-api/src/lib/sagas.ts @@ -8,8 +8,11 @@ import { OrderDetails, OrderRevision } from './entities'; export enum CreateOrderSagaState { STARTED = 'STARTED', CUSTOMER_VALIDATED = 'CUSTOMER_VALIDATED', - PAYMENT_RESERVED = 'PAYMENT_RESERVED', - CANCELLED = 'CANCELLED', + PAYMENT_AUTHORIZED = 'PAYMENT_AUTHORIZED', + WAITING_FOR_CONFIRMATION = 'WAITING_FOR_CONFIRMATION', + REJECTED = 'REJECTED', + CONFIRMED = 'CONFIRMED', + APPROVED = 'APPROVED', } export class CreateOrderSagaData { diff --git a/order-service-api/src/lib/services.ts b/order-service-api/src/lib/services.ts index 5e1a521..0c2a10c 100644 --- a/order-service-api/src/lib/services.ts +++ b/order-service-api/src/lib/services.ts @@ -1,6 +1,5 @@ import { restate, RestateService } from 'deepkit-restate'; import { UUID } from '@deepkit/type'; -import { ItemNotFound } from '@deepkit/orm'; import { Restaurant, @@ -10,7 +9,11 @@ import { import { Order } from './entities'; import { CreateOrderRequest } from './dtos'; -import { OrderMinimumNotMetException } from './replies'; +import { + OrderApproved, + OrderMinimumNotMetException, + OrderNotFound, +} from './replies'; export interface OrderServiceHandlers { create(request: CreateOrderRequest): Promise; @@ -21,7 +24,7 @@ export interface OrderServiceHandlers { cancel(id: UUID): Promise; confirmCancel(id: UUID): Promise; reject(id: UUID): Promise; - approve(id: UUID): Promise; + approve(id: UUID): Promise; createMenu(event: RestaurantCreatedEvent): Promise; reviseMenu(event: RestaurantCreatedEvent): Promise; } @@ -29,5 +32,5 @@ export interface OrderServiceHandlers { export type OrderServiceApi = RestateService< 'Order', OrderServiceHandlers, - [ItemNotFound, OrderMinimumNotMetException] + [OrderNotFound, OrderMinimumNotMetException] >; diff --git a/order-service/src/order.service.ts b/order-service/src/order.service.ts index 62bf027..3d82dd3 100644 --- a/order-service/src/order.service.ts +++ b/order-service/src/order.service.ts @@ -47,7 +47,7 @@ export class OrderService implements OrderServiceHandlers { throw new OrderNotFound(id); } order.cancel(); - await this.order.persist(order); + await this.order.save(order); return order; } diff --git a/order-service/src/sagas/create-order.saga.ts b/order-service/src/sagas/create-order.saga.ts index 80eb5d5..ccc40bf 100644 --- a/order-service/src/sagas/create-order.saga.ts +++ b/order-service/src/sagas/create-order.saga.ts @@ -8,10 +8,12 @@ import { cast } from '@deepkit/type'; import { Writable } from 'type-fest'; import { CustomerServiceApi } from '@ftgo/customer-service-api'; -import { PaymentReserved, PaymentServiceApi } from '@ftgo/payment-service-api'; +import { + PaymentAuthorized, + PaymentServiceApi, +} from '@ftgo/payment-service-api'; import { KitchenServiceApi, - Ticket, TicketConfirmed, TicketCreated, TicketDetails, @@ -20,6 +22,8 @@ import { CreateOrderSagaApi, CreateOrderSagaData, CreateOrderSagaState, + OrderApproved, + OrderRejected, OrderServiceApi, } from '@ftgo/order-service-api'; @@ -29,22 +33,22 @@ export class CreateOrderSaga extends Saga { readonly definition = this.step() .compensate(this.reject) + .onReply(this.handleRejected) .step() .invoke(this.validate) .step() - .invoke(this.reservePayment) - .onReply(this.handlePaymentReserved) - .compensate(this.reversePayment) + .invoke(this.authorizePayment) + .onReply(this.handlePaymentAuthorized) + .compensate(this.reversePaymentAuthorization) .step() .invoke(this.createTicket) .onReply(this.handleTicketCreated) .compensate(this.cancelTicket) .step() - .invoke(this.authorize) - .step() .invoke(this.waitForTicketConfirmation) .step() .invoke(this.approve) + .onReply(this.handleApproved) .build(); constructor( @@ -61,34 +65,38 @@ export class CreateOrderSaga extends Saga { return this.order.reject(orderId); } + handleRejected(data: Writable) { + data.state = CreateOrderSagaState.REJECTED; + } + validate({ orderDetails: { customerId, orderTotal }, orderId, }: CreateOrderSagaData) { - // validate that customer can reserve the money + // validate that customer can authorize the money return this.customer.validateOrder(customerId, orderId, orderTotal); } - reservePayment({ + authorizePayment({ orderDetails: { customerId, orderTotal }, orderId, }: CreateOrderSagaData) { - return this.payment.reserve(customerId, orderId, orderTotal); + return this.payment.authorize(customerId, orderId, orderTotal); } - handlePaymentReserved( + handlePaymentAuthorized( data: Writable, - { paymentId }: PaymentReserved, + { paymentId }: PaymentAuthorized, ) { data.paymentId = paymentId; - data.state = CreateOrderSagaState.PAYMENT_RESERVED; + data.state = CreateOrderSagaState.PAYMENT_AUTHORIZED; } - reversePayment({ paymentId }: CreateOrderSagaData) { + reversePaymentAuthorization({ paymentId }: CreateOrderSagaData) { if (!paymentId) { throw new Error('Missing payment id'); } - return this.payment.reverse(paymentId); + return this.payment.reverseAuthorization(paymentId); } async createTicket({ @@ -109,6 +117,7 @@ export class CreateOrderSaga extends Saga { data: Writable, { ticketId }: TicketCreated, ) { + data.state = CreateOrderSagaState.WAITING_FOR_CONFIRMATION; data.ticketId = ticketId; } @@ -119,19 +128,16 @@ export class CreateOrderSaga extends Saga { return this.kitchen.cancelTicket(ticketId); } - // TODO: should payment be processed upon ticket confirmation or after delivery? - authorize({ - orderDetails: { customerId, orderTotal }, - orderId, - }: CreateOrderSagaData) { - return this.payment.authorize(customerId, orderId, orderTotal); - } - - async waitForTicketConfirmation() { + async waitForTicketConfirmation(data: Writable) { await this.#confirmTicketAwakeable!.promise; + data.state = CreateOrderSagaState.CONFIRMED; } approve({ orderId }: CreateOrderSagaData) { return this.order.approve(orderId); } + + handleApproved(data: Writable) { + data.state = CreateOrderSagaState.APPROVED; + } } diff --git a/package.json b/package.json index 7b81e62..e40755c 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@restatedev/restate-sdk": "1.2.0", "deepkit-restate": "0.0.47", "kafkajs": "2.2.4", + "stripe": "^16.8.0", "tslib": "2.6.3" }, "devDependencies": { diff --git a/payment-service-api/src/lib/entities.ts b/payment-service-api/src/lib/entities.ts index fa4292c..8763551 100644 --- a/payment-service-api/src/lib/entities.ts +++ b/payment-service-api/src/lib/entities.ts @@ -1,6 +1,51 @@ -import { entity, Unique, uuid, UUID } from '@deepkit/type'; +import { Writable } from 'type-fest'; +import { + entity, + float, + JSONPartial, + PrimaryKey, + Unique, + uuid, + UUID, +} from '@deepkit/type'; + +import { Money, UnsupportedStateTransitionException } from '@ftgo/common'; + +export enum PaymentState { + AUTHORIZED = 'AUTHORIZED', + REFUNDED = 'REFUNDED', + REVERSED = 'REVERSED', + AUTHORIZATION_REVERSED = 'AUTHORIZATION_REVERSED', + CANCELLED = 'CANCELLED', +} @entity.name('payment') export class Payment { - readonly id: UUID = uuid(); + readonly id: UUID & PrimaryKey = uuid(); + readonly orderId: UUID; + readonly orderTotal: Money; + readonly stripePaymentIntentId: UUID & Unique; + readonly status: string; // stripe payment intent status + readonly state: PaymentState = PaymentState.AUTHORIZED; + + static create(data: JSONPartial) { + return Object.assign(new Payment(), data); + } + + cancel(this: Writable) { + if (this.state !== PaymentState.AUTHORIZED) { + throw new UnsupportedStateTransitionException(this.state); + } + this.state = PaymentState.CANCELLED; + } +} + +@entity.name('stripe-customer') +export class StripeCustomer { + readonly id: UUID & PrimaryKey; + readonly customerId: UUID & Unique; + + static create(data: JSONPartial) { + return Object.assign(new StripeCustomer(), data); + } } diff --git a/payment-service-api/src/lib/replies.ts b/payment-service-api/src/lib/replies.ts index 33f7fb6..59a3478 100644 --- a/payment-service-api/src/lib/replies.ts +++ b/payment-service-api/src/lib/replies.ts @@ -1,14 +1,10 @@ import { UUID } from '@deepkit/type'; export class PaymentAuthorized { - constructor(readonly customerId: UUID) {} -} - -export class PaymentReserved { constructor(readonly paymentId: UUID) {} } -export class PaymentReversed { +export class PaymentAuthorizationReversed { constructor(readonly paymentId: UUID) {} } @@ -20,3 +16,15 @@ export class PaymentAuthorizationFailed extends Error { super(); } } + +export class PaymentNotFound extends Error { + constructor(readonly paymentId: UUID) { + super(); + } +} + +export class StripeCustomerNotFound extends Error { + constructor(readonly customerId: UUID) { + super(); + } +} diff --git a/payment-service-api/src/lib/services.ts b/payment-service-api/src/lib/services.ts index d94e4fd..7023daf 100644 --- a/payment-service-api/src/lib/services.ts +++ b/payment-service-api/src/lib/services.ts @@ -1,28 +1,26 @@ import { RestateService } from 'deepkit-restate'; import { UUID } from '@deepkit/type'; -import { CustomerCreatedEvent } from '@ftgo/customer-service-api'; import { Money } from '@ftgo/common'; +import { Payment } from './entities'; import { PaymentAuthorizationFailed, PaymentAuthorized, - PaymentReserved, + StripeCustomerNotFound, } from './replies'; -import { Payment } from './entities'; export interface PaymentServiceHandlers { - createCustomer(event: CustomerCreatedEvent): Promise; - reserve( + authorize( customerId: UUID, orderId: UUID, orderTotal: Money, - ): Promise; - reverse(paymentId: UUID): Promise; + ): Promise; + reverseAuthorization(paymentId: UUID): Promise; } export type PaymentServiceApi = RestateService< 'Payment', PaymentServiceHandlers, - [Payment, PaymentAuthorizationFailed] + [Payment, PaymentAuthorizationFailed, StripeCustomerNotFound] >; diff --git a/payment-service/src/config.ts b/payment-service/src/config.ts index 587dd92..a5db55d 100644 --- a/payment-service/src/config.ts +++ b/payment-service/src/config.ts @@ -1,3 +1,11 @@ import { ServiceConfig } from '@ftgo/common'; -export class PaymentServiceConfig extends ServiceConfig {} +export class StripeConfig { + readonly apiKey: string; + readonly maxNetworkRetries: number = 0; + readonly timeout: number = 80000; +} + +export class PaymentServiceConfig extends ServiceConfig { + readonly stripe: StripeConfig; +} diff --git a/payment-service/src/main.ts b/payment-service/src/main.ts index 3bc8d19..c4c165c 100644 --- a/payment-service/src/main.ts +++ b/payment-service/src/main.ts @@ -3,17 +3,24 @@ import { FrameworkModule } from '@deepkit/framework'; import { RestateModule } from 'deepkit-restate'; import { provideDatabase } from '@ftgo/common'; -import { Payment } from '@ftgo/payment-service-api'; +import { Payment, StripeCustomer } from '@ftgo/payment-service-api'; import { PaymentServiceConfig } from './config'; import { PaymentService } from './payment.service'; import { PaymentRepository } from './payment.repository'; +import { Stripe } from './stripe'; +import { StripeCustomerRepository } from './stripe-customer.repository'; void new App({ config: PaymentServiceConfig, imports: [new FrameworkModule(), new RestateModule()], controllers: [PaymentService], - providers: [provideDatabase([Payment]), PaymentRepository], + providers: [ + provideDatabase([Payment, StripeCustomer]), + PaymentRepository, + StripeCustomerRepository, + Stripe, + ], }) .loadConfigFromEnv({ prefix: '' }) .run(); diff --git a/payment-service/src/payment.repository.ts b/payment-service/src/payment.repository.ts index 4405827..9fbeb63 100644 --- a/payment-service/src/payment.repository.ts +++ b/payment-service/src/payment.repository.ts @@ -1,4 +1,17 @@ +import { UUID } from '@deepkit/type'; + import { RestateRepository } from '@ftgo/common'; -import { Payment } from '@ftgo/payment-service-api'; +import { Payment, PaymentNotFound } from '@ftgo/payment-service-api'; -export class PaymentRepository extends RestateRepository {} +export class PaymentRepository extends RestateRepository { + /** + * @throws PaymentNotFound + */ + async findById(id: UUID): Promise { + const payment = await this.find({ id }); + if (!payment) { + throw new PaymentNotFound(id); + } + return payment; + } +} diff --git a/payment-service/src/payment.service.ts b/payment-service/src/payment.service.ts index 2993752..fa58d0d 100644 --- a/payment-service/src/payment.service.ts +++ b/payment-service/src/payment.service.ts @@ -1,30 +1,122 @@ -import { restate } from 'deepkit-restate'; +import { restate, RestateServiceContext } from 'deepkit-restate'; import { UUID } from '@deepkit/type'; import { CustomerCreatedEvent } from '@ftgo/customer-service-api'; import { Money } from '@ftgo/common'; import { - PaymentReserved, + PaymentAuthorizationFailed, + PaymentAuthorizationReversed, + PaymentAuthorized, PaymentServiceApi, PaymentServiceHandlers, } from '@ftgo/payment-service-api'; import { PaymentRepository } from './payment.repository'; +import { StripeCustomerRepository } from './stripe-customer.repository'; +import { Stripe } from './stripe'; +import { StripePaymentIntent } from './types'; @restate.service() export class PaymentService implements PaymentServiceHandlers { - constructor(private readonly payment: PaymentRepository) {} + constructor( + private readonly payment: PaymentRepository, + private readonly stripeCustomer: StripeCustomerRepository, + private readonly stripe: Stripe, + private readonly ctx: RestateServiceContext, + ) {} @(restate.event().handler()) - async createCustomer({ customer }: CustomerCreatedEvent): Promise {} + async handleCustomerCreated({ + id, + email, + name, + phoneNumber, + }: CustomerCreatedEvent): Promise { + const { id: stripeCustomerId } = await this.ctx.run<{ id: UUID }>(() => + this.stripe.customers.create({ + email, + phone: phoneNumber as string, + name: `${name.firstName} ${name.lastName}`, + metadata: { + customerId: id, + }, + }), + ); + + await this.stripeCustomer.create({ + id: stripeCustomerId, + customerId: id, + }); + } @restate.handler() - async reserve( + async authorize( customerId: UUID, orderId: UUID, orderTotal: Money, - ): Promise {} + ): Promise { + const stripeCustomer = + await this.stripeCustomer.findByCustomerId(customerId); + + const [paymentIntent, error] = await this.ctx.run< + [StripePaymentIntent, Error?] + >(async () => { + try { + return [ + await this.stripe.paymentIntents.create({ + customer: stripeCustomer.id, + currency: 'usd', + automatic_payment_methods: { + enabled: true, + }, + confirmation_method: 'manual', + capture_method: 'manual', + payment_method_options: { + card: { + capture_method: 'manual', + }, + }, + amount: orderTotal.cents, + }), + ]; + } catch (err) { + if (err.type === 'StripeCardError') { + return [err.payment_intent, err]; + } + + throw err; + } + }); + + const payment = await this.payment.create({ + stripePaymentIntentId: paymentIntent.id, + status: paymentIntent.status, + customerId, + orderTotal, + orderId, + }); + + if (error) { + throw new PaymentAuthorizationFailed(customerId, error.message); + } + + return new PaymentAuthorized(payment.id); + } @restate.handler() - async reverse(paymentId: UUID): Promise {} + async reverseAuthorization( + paymentId: UUID, + ): Promise { + const payment = await this.payment.findById(paymentId); + + payment.cancel(); + + await this.ctx.run(() => + this.stripe.paymentIntents.cancel(payment.stripePaymentIntentId), + ); + + await this.payment.save(payment); + + return new PaymentAuthorizationReversed(paymentId); + } } diff --git a/payment-service/src/stripe-customer.repository.ts b/payment-service/src/stripe-customer.repository.ts new file mode 100644 index 0000000..8a160f2 --- /dev/null +++ b/payment-service/src/stripe-customer.repository.ts @@ -0,0 +1,20 @@ +import { UUID } from '@deepkit/type'; + +import { RestateRepository } from '@ftgo/common'; +import { + StripeCustomer, + StripeCustomerNotFound, +} from '@ftgo/payment-service-api'; + +export class StripeCustomerRepository extends RestateRepository { + /** + * @throws StripeCustomerNotFound + */ + async findByCustomerId(customerId: UUID): Promise { + const stripeCustomer = await this.find({ customerId }); + if (!stripeCustomer) { + throw new StripeCustomerNotFound(customerId); + } + return stripeCustomer; + } +} diff --git a/payment-service/src/stripe.ts b/payment-service/src/stripe.ts new file mode 100644 index 0000000..4946618 --- /dev/null +++ b/payment-service/src/stripe.ts @@ -0,0 +1,13 @@ +import _Stripe from 'stripe'; + +import { StripeConfig } from './config'; + +export class Stripe extends _Stripe { + constructor({ apiKey, maxNetworkRetries, timeout }: StripeConfig) { + super(apiKey, { + apiVersion: '2024-06-20', + maxNetworkRetries, + timeout, + }); + } +} diff --git a/payment-service/src/types.ts b/payment-service/src/types.ts new file mode 100644 index 0000000..c762725 --- /dev/null +++ b/payment-service/src/types.ts @@ -0,0 +1,13 @@ +import { UUID } from '@deepkit/type'; + +interface PaymentIntentLastPaymentError { + readonly code: string; + readonly message?: string; +} + +export interface StripePaymentIntent { + readonly id: UUID; + readonly cancellation_reason: string | null; + readonly last_payment_error: PaymentIntentLastPaymentError | null; + readonly status: string; +}