@open-mercato/core 0.6.7-develop.6572.1.3d8e83062f → 0.6.7-develop.6574.1.05dcf72ba8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +2 -2
- package/dist/generated/entities/gateway_payment_operation/index.js +35 -0
- package/dist/generated/entities/gateway_payment_operation/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +1 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +18 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/payment_gateways/api/cancel/route.js +2 -1
- package/dist/modules/payment_gateways/api/cancel/route.js.map +2 -2
- package/dist/modules/payment_gateways/api/capture/route.js +2 -1
- package/dist/modules/payment_gateways/api/capture/route.js.map +2 -2
- package/dist/modules/payment_gateways/api/refund/route.js +2 -1
- package/dist/modules/payment_gateways/api/refund/route.js.map +2 -2
- package/dist/modules/payment_gateways/data/entities.js +67 -0
- package/dist/modules/payment_gateways/data/entities.js.map +2 -2
- package/dist/modules/payment_gateways/data/validators.js +6 -3
- package/dist/modules/payment_gateways/data/validators.js.map +2 -2
- package/dist/modules/payment_gateways/lib/gateway-service.js +145 -111
- package/dist/modules/payment_gateways/lib/gateway-service.js.map +2 -2
- package/dist/modules/payment_gateways/lib/payment-operation-idempotency.js +183 -0
- package/dist/modules/payment_gateways/lib/payment-operation-idempotency.js.map +7 -0
- package/dist/modules/payment_gateways/migrations/Migration20260709220735_payment_gateways.js +13 -0
- package/dist/modules/payment_gateways/migrations/Migration20260709220735_payment_gateways.js.map +7 -0
- package/generated/entities/gateway_payment_operation/index.ts +16 -0
- package/generated/entities.ids.generated.ts +1 -0
- package/generated/entity-fields-registry.ts +18 -0
- package/package.json +7 -7
- package/src/modules/payment_gateways/api/cancel/route.ts +1 -0
- package/src/modules/payment_gateways/api/capture/route.ts +1 -0
- package/src/modules/payment_gateways/api/refund/route.ts +1 -0
- package/src/modules/payment_gateways/data/entities.ts +59 -0
- package/src/modules/payment_gateways/data/validators.ts +3 -0
- package/src/modules/payment_gateways/lib/gateway-service.ts +168 -117
- package/src/modules/payment_gateways/lib/payment-operation-idempotency.ts +238 -0
- package/src/modules/payment_gateways/migrations/.snapshot-open-mercato.json +331 -1
- package/src/modules/payment_gateways/migrations/Migration20260709220735_payment_gateways.ts +12 -0
|
@@ -52,7 +52,8 @@ async function POST(req) {
|
|
|
52
52
|
const result = await service.cancelPayment(
|
|
53
53
|
parsed.data.transactionId,
|
|
54
54
|
parsed.data.reason,
|
|
55
|
-
{ organizationId: auth.orgId, tenantId: auth.tenantId }
|
|
55
|
+
{ organizationId: auth.orgId, tenantId: auth.tenantId },
|
|
56
|
+
parsed.data.operationId
|
|
56
57
|
);
|
|
57
58
|
await runPaymentGatewayMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {
|
|
58
59
|
tenantId: auth.tenantId,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/payment_gateways/api/cancel/route.ts"],
|
|
4
|
-
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { cancelSchema } from '../../data/validators'\nimport type { PaymentGatewayService } from '../../lib/gateway-service'\nimport { paymentGatewaysTag } from '../openapi'\nimport {\n resolveUserFeatures,\n runPaymentGatewayMutationGuardAfterSuccess,\n runPaymentGatewayMutationGuards,\n} from '../guards'\n\nconst gatewayTransactionResourceKind = 'payment_gateways.gateway_transaction'\n\nexport const metadata = {\n path: '/payment_gateways/cancel',\n POST: { requireAuth: true, requireFeatures: ['payment_gateways.manage'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n const payload = await readJsonSafe<unknown>(req)\n const parsed = cancelSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n\n const container = await createRequestContainer()\n const guardResult = await runPaymentGatewayMutationGuards(\n container,\n {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: auth.sub ?? '',\n resourceKind: gatewayTransactionResourceKind,\n resourceId: parsed.data.transactionId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: parsed.data as Record<string, unknown>,\n },\n resolveUserFeatures(auth),\n )\n if (!guardResult.ok) {\n return NextResponse.json(\n guardResult.errorBody ?? { error: 'Operation blocked by guard' },\n { status: guardResult.errorStatus ?? 422 },\n )\n }\n\n const service = container.resolve('paymentGatewayService') as PaymentGatewayService\n\n try {\n const result = await service.cancelPayment(\n parsed.data.transactionId,\n parsed.data.reason,\n { organizationId: auth.orgId as string, tenantId: auth.tenantId },\n )\n await runPaymentGatewayMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: auth.sub ?? '',\n resourceKind: gatewayTransactionResourceKind,\n resourceId: parsed.data.transactionId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n })\n return NextResponse.json(result)\n } catch (err: unknown) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n const message = err instanceof Error ? err.message : 'Cancel failed'\n return NextResponse.json({ error: message }, { status: 502 })\n }\n}\n\nexport const openApi = {\n tags: [paymentGatewaysTag],\n summary: 'Cancel/void an authorized payment',\n methods: {\n POST: {\n summary: 'Cancel payment',\n tags: [paymentGatewaysTag],\n responses: [\n { status: 200, description: 'Payment cancelled' },\n { status: 409, description: 'Invalid payment status transition' },\n { status: 422, description: 'Invalid payload' },\n { status: 502, description: 'Gateway provider error' },\n ],\n },\n },\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AACvC,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAE7B,SAAS,0BAA0B;AACnC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,MAAM,iCAAiC;AAEhC,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,yBAAyB,EAAE;AAC1E;AAEA,eAAsB,KAAK,KAAc;AACvC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM,YAAY,CAAC,KAAK,OAAO;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AAEA,QAAM,UAAU,MAAM,aAAsB,GAAG;AAC/C,QAAM,SAAS,aAAa,UAAU,OAAO;AAC7C,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,OAAO,mBAAmB,SAAS,OAAO,MAAM,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzG;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,cAAc,MAAM;AAAA,IACxB;AAAA,IACA;AAAA,MACE,UAAU,KAAK;AAAA,MACf,gBAAgB,KAAK;AAAA,MACrB,QAAQ,KAAK,OAAO;AAAA,MACpB,cAAc;AAAA,MACd,YAAY,OAAO,KAAK;AAAA,MACxB,WAAW;AAAA,MACX,eAAe,IAAI;AAAA,MACnB,gBAAgB,IAAI;AAAA,MACpB,iBAAiB,OAAO;AAAA,IAC1B;AAAA,IACA,oBAAoB,IAAI;AAAA,EAC1B;AACA,MAAI,CAAC,YAAY,IAAI;AACnB,WAAO,aAAa;AAAA,MAClB,YAAY,aAAa,EAAE,OAAO,6BAA6B;AAAA,MAC/D,EAAE,QAAQ,YAAY,eAAe,IAAI;AAAA,IAC3C;AAAA,EACF;AAEA,QAAM,UAAU,UAAU,QAAQ,uBAAuB;AAEzD,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,EAAE,gBAAgB,KAAK,OAAiB,UAAU,KAAK,SAAS;AAAA,
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { cancelSchema } from '../../data/validators'\nimport type { PaymentGatewayService } from '../../lib/gateway-service'\nimport { paymentGatewaysTag } from '../openapi'\nimport {\n resolveUserFeatures,\n runPaymentGatewayMutationGuardAfterSuccess,\n runPaymentGatewayMutationGuards,\n} from '../guards'\n\nconst gatewayTransactionResourceKind = 'payment_gateways.gateway_transaction'\n\nexport const metadata = {\n path: '/payment_gateways/cancel',\n POST: { requireAuth: true, requireFeatures: ['payment_gateways.manage'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n const payload = await readJsonSafe<unknown>(req)\n const parsed = cancelSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n\n const container = await createRequestContainer()\n const guardResult = await runPaymentGatewayMutationGuards(\n container,\n {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: auth.sub ?? '',\n resourceKind: gatewayTransactionResourceKind,\n resourceId: parsed.data.transactionId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: parsed.data as Record<string, unknown>,\n },\n resolveUserFeatures(auth),\n )\n if (!guardResult.ok) {\n return NextResponse.json(\n guardResult.errorBody ?? { error: 'Operation blocked by guard' },\n { status: guardResult.errorStatus ?? 422 },\n )\n }\n\n const service = container.resolve('paymentGatewayService') as PaymentGatewayService\n\n try {\n const result = await service.cancelPayment(\n parsed.data.transactionId,\n parsed.data.reason,\n { organizationId: auth.orgId as string, tenantId: auth.tenantId },\n parsed.data.operationId,\n )\n await runPaymentGatewayMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: auth.sub ?? '',\n resourceKind: gatewayTransactionResourceKind,\n resourceId: parsed.data.transactionId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n })\n return NextResponse.json(result)\n } catch (err: unknown) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n const message = err instanceof Error ? err.message : 'Cancel failed'\n return NextResponse.json({ error: message }, { status: 502 })\n }\n}\n\nexport const openApi = {\n tags: [paymentGatewaysTag],\n summary: 'Cancel/void an authorized payment',\n methods: {\n POST: {\n summary: 'Cancel payment',\n tags: [paymentGatewaysTag],\n responses: [\n { status: 200, description: 'Payment cancelled' },\n { status: 409, description: 'Invalid payment status transition' },\n { status: 422, description: 'Invalid payload' },\n { status: 502, description: 'Gateway provider error' },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -52,7 +52,8 @@ async function POST(req) {
|
|
|
52
52
|
const result = await service.capturePayment(
|
|
53
53
|
parsed.data.transactionId,
|
|
54
54
|
parsed.data.amount,
|
|
55
|
-
{ organizationId: auth.orgId, tenantId: auth.tenantId }
|
|
55
|
+
{ organizationId: auth.orgId, tenantId: auth.tenantId },
|
|
56
|
+
parsed.data.operationId
|
|
56
57
|
);
|
|
57
58
|
await runPaymentGatewayMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {
|
|
58
59
|
tenantId: auth.tenantId,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/payment_gateways/api/capture/route.ts"],
|
|
4
|
-
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { captureSchema } from '../../data/validators'\nimport type { PaymentGatewayService } from '../../lib/gateway-service'\nimport { paymentGatewaysTag } from '../openapi'\nimport {\n resolveUserFeatures,\n runPaymentGatewayMutationGuardAfterSuccess,\n runPaymentGatewayMutationGuards,\n} from '../guards'\n\nconst gatewayTransactionResourceKind = 'payment_gateways.gateway_transaction'\n\nexport const metadata = {\n path: '/payment_gateways/capture',\n POST: { requireAuth: true, requireFeatures: ['payment_gateways.capture'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n const payload = await readJsonSafe<unknown>(req)\n const parsed = captureSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n\n const container = await createRequestContainer()\n const guardResult = await runPaymentGatewayMutationGuards(\n container,\n {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: auth.sub ?? '',\n resourceKind: gatewayTransactionResourceKind,\n resourceId: parsed.data.transactionId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: parsed.data as Record<string, unknown>,\n },\n resolveUserFeatures(auth),\n )\n if (!guardResult.ok) {\n return NextResponse.json(\n guardResult.errorBody ?? { error: 'Operation blocked by guard' },\n { status: guardResult.errorStatus ?? 422 },\n )\n }\n\n const service = container.resolve('paymentGatewayService') as PaymentGatewayService\n\n try {\n const result = await service.capturePayment(\n parsed.data.transactionId,\n parsed.data.amount,\n { organizationId: auth.orgId as string, tenantId: auth.tenantId },\n )\n await runPaymentGatewayMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: auth.sub ?? '',\n resourceKind: gatewayTransactionResourceKind,\n resourceId: parsed.data.transactionId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n })\n return NextResponse.json(result)\n } catch (err: unknown) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n const message = err instanceof Error ? err.message : 'Capture failed'\n return NextResponse.json({ error: message }, { status: 502 })\n }\n}\n\nexport const openApi = {\n tags: [paymentGatewaysTag],\n summary: 'Capture an authorized payment',\n methods: {\n POST: {\n summary: 'Capture payment',\n tags: [paymentGatewaysTag],\n responses: [\n { status: 200, description: 'Payment captured' },\n { status: 409, description: 'Invalid payment status transition' },\n { status: 422, description: 'Invalid payload' },\n { status: 502, description: 'Gateway provider error' },\n ],\n },\n },\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AACvC,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAE9B,SAAS,0BAA0B;AACnC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,MAAM,iCAAiC;AAEhC,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,0BAA0B,EAAE;AAC3E;AAEA,eAAsB,KAAK,KAAc;AACvC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM,YAAY,CAAC,KAAK,OAAO;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AAEA,QAAM,UAAU,MAAM,aAAsB,GAAG;AAC/C,QAAM,SAAS,cAAc,UAAU,OAAO;AAC9C,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,OAAO,mBAAmB,SAAS,OAAO,MAAM,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzG;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,cAAc,MAAM;AAAA,IACxB;AAAA,IACA;AAAA,MACE,UAAU,KAAK;AAAA,MACf,gBAAgB,KAAK;AAAA,MACrB,QAAQ,KAAK,OAAO;AAAA,MACpB,cAAc;AAAA,MACd,YAAY,OAAO,KAAK;AAAA,MACxB,WAAW;AAAA,MACX,eAAe,IAAI;AAAA,MACnB,gBAAgB,IAAI;AAAA,MACpB,iBAAiB,OAAO;AAAA,IAC1B;AAAA,IACA,oBAAoB,IAAI;AAAA,EAC1B;AACA,MAAI,CAAC,YAAY,IAAI;AACnB,WAAO,aAAa;AAAA,MAClB,YAAY,aAAa,EAAE,OAAO,6BAA6B;AAAA,MAC/D,EAAE,QAAQ,YAAY,eAAe,IAAI;AAAA,IAC3C;AAAA,EACF;AAEA,QAAM,UAAU,UAAU,QAAQ,uBAAuB;AAEzD,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,EAAE,gBAAgB,KAAK,OAAiB,UAAU,KAAK,SAAS;AAAA,
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { captureSchema } from '../../data/validators'\nimport type { PaymentGatewayService } from '../../lib/gateway-service'\nimport { paymentGatewaysTag } from '../openapi'\nimport {\n resolveUserFeatures,\n runPaymentGatewayMutationGuardAfterSuccess,\n runPaymentGatewayMutationGuards,\n} from '../guards'\n\nconst gatewayTransactionResourceKind = 'payment_gateways.gateway_transaction'\n\nexport const metadata = {\n path: '/payment_gateways/capture',\n POST: { requireAuth: true, requireFeatures: ['payment_gateways.capture'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n const payload = await readJsonSafe<unknown>(req)\n const parsed = captureSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n\n const container = await createRequestContainer()\n const guardResult = await runPaymentGatewayMutationGuards(\n container,\n {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: auth.sub ?? '',\n resourceKind: gatewayTransactionResourceKind,\n resourceId: parsed.data.transactionId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: parsed.data as Record<string, unknown>,\n },\n resolveUserFeatures(auth),\n )\n if (!guardResult.ok) {\n return NextResponse.json(\n guardResult.errorBody ?? { error: 'Operation blocked by guard' },\n { status: guardResult.errorStatus ?? 422 },\n )\n }\n\n const service = container.resolve('paymentGatewayService') as PaymentGatewayService\n\n try {\n const result = await service.capturePayment(\n parsed.data.transactionId,\n parsed.data.amount,\n { organizationId: auth.orgId as string, tenantId: auth.tenantId },\n parsed.data.operationId,\n )\n await runPaymentGatewayMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: auth.sub ?? '',\n resourceKind: gatewayTransactionResourceKind,\n resourceId: parsed.data.transactionId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n })\n return NextResponse.json(result)\n } catch (err: unknown) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n const message = err instanceof Error ? err.message : 'Capture failed'\n return NextResponse.json({ error: message }, { status: 502 })\n }\n}\n\nexport const openApi = {\n tags: [paymentGatewaysTag],\n summary: 'Capture an authorized payment',\n methods: {\n POST: {\n summary: 'Capture payment',\n tags: [paymentGatewaysTag],\n responses: [\n { status: 200, description: 'Payment captured' },\n { status: 409, description: 'Invalid payment status transition' },\n { status: 422, description: 'Invalid payload' },\n { status: 502, description: 'Gateway provider error' },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -53,7 +53,8 @@ async function POST(req) {
|
|
|
53
53
|
parsed.data.transactionId,
|
|
54
54
|
parsed.data.amount,
|
|
55
55
|
parsed.data.reason,
|
|
56
|
-
{ organizationId: auth.orgId, tenantId: auth.tenantId }
|
|
56
|
+
{ organizationId: auth.orgId, tenantId: auth.tenantId },
|
|
57
|
+
parsed.data.operationId
|
|
57
58
|
);
|
|
58
59
|
await runPaymentGatewayMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {
|
|
59
60
|
tenantId: auth.tenantId,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/payment_gateways/api/refund/route.ts"],
|
|
4
|
-
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { refundSchema } from '../../data/validators'\nimport type { PaymentGatewayService } from '../../lib/gateway-service'\nimport { paymentGatewaysTag } from '../openapi'\nimport {\n resolveUserFeatures,\n runPaymentGatewayMutationGuardAfterSuccess,\n runPaymentGatewayMutationGuards,\n} from '../guards'\n\nconst gatewayTransactionResourceKind = 'payment_gateways.gateway_transaction'\n\nexport const metadata = {\n path: '/payment_gateways/refund',\n POST: { requireAuth: true, requireFeatures: ['payment_gateways.refund'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n const payload = await readJsonSafe<unknown>(req)\n const parsed = refundSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n\n const container = await createRequestContainer()\n const guardResult = await runPaymentGatewayMutationGuards(\n container,\n {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: auth.sub ?? '',\n resourceKind: gatewayTransactionResourceKind,\n resourceId: parsed.data.transactionId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: parsed.data as Record<string, unknown>,\n },\n resolveUserFeatures(auth),\n )\n if (!guardResult.ok) {\n return NextResponse.json(\n guardResult.errorBody ?? { error: 'Operation blocked by guard' },\n { status: guardResult.errorStatus ?? 422 },\n )\n }\n\n const service = container.resolve('paymentGatewayService') as PaymentGatewayService\n\n try {\n const result = await service.refundPayment(\n parsed.data.transactionId,\n parsed.data.amount,\n parsed.data.reason,\n { organizationId: auth.orgId as string, tenantId: auth.tenantId },\n )\n await runPaymentGatewayMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: auth.sub ?? '',\n resourceKind: gatewayTransactionResourceKind,\n resourceId: parsed.data.transactionId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n })\n return NextResponse.json(result)\n } catch (err: unknown) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n const message = err instanceof Error ? err.message : 'Refund failed'\n return NextResponse.json({ error: message }, { status: 502 })\n }\n}\n\nexport const openApi = {\n tags: [paymentGatewaysTag],\n summary: 'Refund a captured payment',\n methods: {\n POST: {\n summary: 'Refund payment',\n tags: [paymentGatewaysTag],\n responses: [\n { status: 200, description: 'Payment refunded' },\n { status: 409, description: 'Invalid payment status transition' },\n { status: 422, description: 'Invalid payload' },\n { status: 502, description: 'Gateway provider error' },\n ],\n },\n },\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AACvC,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAE7B,SAAS,0BAA0B;AACnC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,MAAM,iCAAiC;AAEhC,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,yBAAyB,EAAE;AAC1E;AAEA,eAAsB,KAAK,KAAc;AACvC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM,YAAY,CAAC,KAAK,OAAO;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AAEA,QAAM,UAAU,MAAM,aAAsB,GAAG;AAC/C,QAAM,SAAS,aAAa,UAAU,OAAO;AAC7C,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,OAAO,mBAAmB,SAAS,OAAO,MAAM,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzG;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,cAAc,MAAM;AAAA,IACxB;AAAA,IACA;AAAA,MACE,UAAU,KAAK;AAAA,MACf,gBAAgB,KAAK;AAAA,MACrB,QAAQ,KAAK,OAAO;AAAA,MACpB,cAAc;AAAA,MACd,YAAY,OAAO,KAAK;AAAA,MACxB,WAAW;AAAA,MACX,eAAe,IAAI;AAAA,MACnB,gBAAgB,IAAI;AAAA,MACpB,iBAAiB,OAAO;AAAA,IAC1B;AAAA,IACA,oBAAoB,IAAI;AAAA,EAC1B;AACA,MAAI,CAAC,YAAY,IAAI;AACnB,WAAO,aAAa;AAAA,MAClB,YAAY,aAAa,EAAE,OAAO,6BAA6B;AAAA,MAC/D,EAAE,QAAQ,YAAY,eAAe,IAAI;AAAA,IAC3C;AAAA,EACF;AAEA,QAAM,UAAU,UAAU,QAAQ,uBAAuB;AAEzD,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,EAAE,gBAAgB,KAAK,OAAiB,UAAU,KAAK,SAAS;AAAA,
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { refundSchema } from '../../data/validators'\nimport type { PaymentGatewayService } from '../../lib/gateway-service'\nimport { paymentGatewaysTag } from '../openapi'\nimport {\n resolveUserFeatures,\n runPaymentGatewayMutationGuardAfterSuccess,\n runPaymentGatewayMutationGuards,\n} from '../guards'\n\nconst gatewayTransactionResourceKind = 'payment_gateways.gateway_transaction'\n\nexport const metadata = {\n path: '/payment_gateways/refund',\n POST: { requireAuth: true, requireFeatures: ['payment_gateways.refund'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n const payload = await readJsonSafe<unknown>(req)\n const parsed = refundSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n\n const container = await createRequestContainer()\n const guardResult = await runPaymentGatewayMutationGuards(\n container,\n {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: auth.sub ?? '',\n resourceKind: gatewayTransactionResourceKind,\n resourceId: parsed.data.transactionId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: parsed.data as Record<string, unknown>,\n },\n resolveUserFeatures(auth),\n )\n if (!guardResult.ok) {\n return NextResponse.json(\n guardResult.errorBody ?? { error: 'Operation blocked by guard' },\n { status: guardResult.errorStatus ?? 422 },\n )\n }\n\n const service = container.resolve('paymentGatewayService') as PaymentGatewayService\n\n try {\n const result = await service.refundPayment(\n parsed.data.transactionId,\n parsed.data.amount,\n parsed.data.reason,\n { organizationId: auth.orgId as string, tenantId: auth.tenantId },\n parsed.data.operationId,\n )\n await runPaymentGatewayMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: auth.sub ?? '',\n resourceKind: gatewayTransactionResourceKind,\n resourceId: parsed.data.transactionId,\n operation: 'update',\n requestMethod: req.method,\n requestHeaders: req.headers,\n })\n return NextResponse.json(result)\n } catch (err: unknown) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n const message = err instanceof Error ? err.message : 'Refund failed'\n return NextResponse.json({ error: message }, { status: 502 })\n }\n}\n\nexport const openApi = {\n tags: [paymentGatewaysTag],\n summary: 'Refund a captured payment',\n methods: {\n POST: {\n summary: 'Refund payment',\n tags: [paymentGatewaysTag],\n responses: [\n { status: 200, description: 'Payment refunded' },\n { status: 409, description: 'Invalid payment status transition' },\n { status: 422, description: 'Invalid payload' },\n { status: 502, description: 'Gateway provider error' },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -91,6 +91,72 @@ GatewayTransaction = __decorateClass([
|
|
|
91
91
|
Index({ properties: ["organizationId", "tenantId", "unifiedStatus"] })
|
|
92
92
|
], GatewayTransaction);
|
|
93
93
|
OptionalProps;
|
|
94
|
+
let GatewayPaymentOperation = class {
|
|
95
|
+
constructor() {
|
|
96
|
+
this.status = "in_progress";
|
|
97
|
+
this.attemptCount = 1;
|
|
98
|
+
this.createdAt = /* @__PURE__ */ new Date();
|
|
99
|
+
this.updatedAt = /* @__PURE__ */ new Date();
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
__decorateClass([
|
|
103
|
+
PrimaryKey({ type: "uuid", defaultRaw: "gen_random_uuid()" })
|
|
104
|
+
], GatewayPaymentOperation.prototype, "id", 2);
|
|
105
|
+
__decorateClass([
|
|
106
|
+
Property({ name: "operation_id", type: "text" })
|
|
107
|
+
], GatewayPaymentOperation.prototype, "operationId", 2);
|
|
108
|
+
__decorateClass([
|
|
109
|
+
Property({ name: "transaction_id", type: "uuid" })
|
|
110
|
+
], GatewayPaymentOperation.prototype, "transactionId", 2);
|
|
111
|
+
__decorateClass([
|
|
112
|
+
Property({ name: "operation_type", type: "text" })
|
|
113
|
+
], GatewayPaymentOperation.prototype, "operationType", 2);
|
|
114
|
+
__decorateClass([
|
|
115
|
+
Property({ name: "provider_key", type: "text" })
|
|
116
|
+
], GatewayPaymentOperation.prototype, "providerKey", 2);
|
|
117
|
+
__decorateClass([
|
|
118
|
+
Property({ name: "request_hash", type: "text" })
|
|
119
|
+
], GatewayPaymentOperation.prototype, "requestHash", 2);
|
|
120
|
+
__decorateClass([
|
|
121
|
+
Property({ name: "provider_idempotency_key", type: "text" })
|
|
122
|
+
], GatewayPaymentOperation.prototype, "providerIdempotencyKey", 2);
|
|
123
|
+
__decorateClass([
|
|
124
|
+
Property({ name: "status", type: "text" })
|
|
125
|
+
], GatewayPaymentOperation.prototype, "status", 2);
|
|
126
|
+
__decorateClass([
|
|
127
|
+
Property({ name: "attempt_token", type: "text" })
|
|
128
|
+
], GatewayPaymentOperation.prototype, "attemptToken", 2);
|
|
129
|
+
__decorateClass([
|
|
130
|
+
Property({ name: "attempt_count", type: "integer" })
|
|
131
|
+
], GatewayPaymentOperation.prototype, "attemptCount", 2);
|
|
132
|
+
__decorateClass([
|
|
133
|
+
Property({ name: "result", type: "jsonb", nullable: true })
|
|
134
|
+
], GatewayPaymentOperation.prototype, "result", 2);
|
|
135
|
+
__decorateClass([
|
|
136
|
+
Property({ name: "lease_expires_at", type: Date, nullable: true })
|
|
137
|
+
], GatewayPaymentOperation.prototype, "leaseExpiresAt", 2);
|
|
138
|
+
__decorateClass([
|
|
139
|
+
Property({ name: "organization_id", type: "uuid" })
|
|
140
|
+
], GatewayPaymentOperation.prototype, "organizationId", 2);
|
|
141
|
+
__decorateClass([
|
|
142
|
+
Property({ name: "tenant_id", type: "uuid" })
|
|
143
|
+
], GatewayPaymentOperation.prototype, "tenantId", 2);
|
|
144
|
+
__decorateClass([
|
|
145
|
+
Property({ name: "created_at", type: Date, onCreate: () => /* @__PURE__ */ new Date() })
|
|
146
|
+
], GatewayPaymentOperation.prototype, "createdAt", 2);
|
|
147
|
+
__decorateClass([
|
|
148
|
+
Property({ name: "updated_at", type: Date, onCreate: () => /* @__PURE__ */ new Date(), onUpdate: () => /* @__PURE__ */ new Date() })
|
|
149
|
+
], GatewayPaymentOperation.prototype, "updatedAt", 2);
|
|
150
|
+
GatewayPaymentOperation = __decorateClass([
|
|
151
|
+
Entity({ tableName: "gateway_payment_operations" }),
|
|
152
|
+
Unique({
|
|
153
|
+
name: "gateway_payment_operations_scope_operation_unique",
|
|
154
|
+
properties: ["operationId", "organizationId", "tenantId"]
|
|
155
|
+
}),
|
|
156
|
+
Index({ properties: ["transactionId", "operationType", "organizationId", "tenantId"] }),
|
|
157
|
+
Index({ properties: ["status", "leaseExpiresAt"] })
|
|
158
|
+
], GatewayPaymentOperation);
|
|
159
|
+
OptionalProps;
|
|
94
160
|
let GatewaySessionInitialization = class {
|
|
95
161
|
constructor() {
|
|
96
162
|
this.createdAt = /* @__PURE__ */ new Date();
|
|
@@ -169,6 +235,7 @@ WebhookProcessedEvent = __decorateClass([
|
|
|
169
235
|
})
|
|
170
236
|
], WebhookProcessedEvent);
|
|
171
237
|
export {
|
|
238
|
+
GatewayPaymentOperation,
|
|
172
239
|
GatewaySessionInitialization,
|
|
173
240
|
GatewayTransaction,
|
|
174
241
|
WebhookProcessedEvent
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/payment_gateways/data/entities.ts"],
|
|
4
|
-
"sourcesContent": ["import { OptionalProps } from '@mikro-orm/core'\nimport { Entity, Index, PrimaryKey, Property, Unique } from '@mikro-orm/decorators/legacy'\n\n@Entity({ tableName: 'gateway_transactions' })\n@Index({ properties: ['paymentId', 'organizationId', 'tenantId'] })\n@Index({ properties: ['providerKey', 'providerSessionId', 'organizationId'] })\n@Index({ properties: ['organizationId', 'tenantId', 'unifiedStatus'] })\nexport class GatewayTransaction {\n [OptionalProps]?: 'unifiedStatus' | 'gatewayStatus' | 'providerSessionId' | 'gatewayPaymentId' | 'gatewayRefundId' | 'redirectUrl' | 'clientSecret' | 'gatewayMetadata' | 'webhookLog' | 'lastWebhookAt' | 'lastPolledAt' | 'expiresAt' | 'createdAt' | 'updatedAt' | 'deletedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'payment_id', type: 'uuid' })\n paymentId!: string\n\n @Property({ name: 'provider_key', type: 'text' })\n providerKey!: string\n\n @Property({ name: 'provider_session_id', type: 'text', nullable: true })\n providerSessionId?: string | null\n\n @Property({ name: 'gateway_payment_id', type: 'text', nullable: true })\n gatewayPaymentId?: string | null\n\n @Property({ name: 'gateway_refund_id', type: 'text', nullable: true })\n gatewayRefundId?: string | null\n\n @Property({ name: 'unified_status', type: 'text' })\n unifiedStatus: string = 'pending'\n\n @Property({ name: 'gateway_status', type: 'text', nullable: true })\n gatewayStatus?: string | null\n\n @Property({ name: 'redirect_url', type: 'text', nullable: true })\n redirectUrl?: string | null\n\n @Property({ name: 'client_secret', type: 'text', nullable: true })\n clientSecret?: string | null\n\n @Property({ name: 'amount', type: 'numeric', precision: 18, scale: 4 })\n amount!: string\n\n @Property({ name: 'currency_code', type: 'text' })\n currencyCode!: string\n\n @Property({ name: 'gateway_metadata', type: 'jsonb', nullable: true })\n gatewayMetadata?: Record<string, unknown> | null\n\n @Property({ name: 'webhook_log', type: 'jsonb', nullable: true })\n webhookLog?: Array<{ eventType: string; receivedAt: string; idempotencyKey: string; unifiedStatus: string; processed: boolean }> | null\n\n @Property({ name: 'last_webhook_at', type: Date, nullable: true })\n lastWebhookAt?: Date | null\n\n @Property({ name: 'last_polled_at', type: Date, nullable: true })\n lastPolledAt?: Date | null\n\n @Property({ name: 'expires_at', type: Date, nullable: true })\n expiresAt?: Date | null\n\n @Property({ name: 'organization_id', type: 'uuid' })\n organizationId!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'gateway_session_initializations' })\n@Unique({\n name: 'gateway_session_initializations_scope_operation_unique',\n properties: ['operationKey', 'providerKey', 'organizationId', 'tenantId'],\n})\nexport class GatewaySessionInitialization {\n [OptionalProps]?: 'claimToken' | 'claimedAt' | 'gatewayTransactionId' | 'createdAt' | 'updatedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'operation_key', type: 'text' })\n operationKey!: string\n\n @Property({ name: 'provider_key', type: 'text' })\n providerKey!: string\n\n @Property({ name: 'claim_token', type: 'uuid', nullable: true })\n claimToken?: string | null\n\n @Property({ name: 'claimed_at', type: Date, nullable: true })\n claimedAt?: Date | null\n\n @Property({ name: 'gateway_transaction_id', type: 'uuid', nullable: true })\n gatewayTransactionId?: string | null\n\n @Property({ name: 'organization_id', type: 'uuid' })\n organizationId!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onCreate: () => new Date(), onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n}\n\n@Entity({ tableName: 'gateway_webhook_events' })\n@Unique({\n name: 'gateway_webhook_events_idempotency_unique',\n properties: ['idempotencyKey', 'providerKey', 'organizationId', 'tenantId'],\n})\nexport class WebhookProcessedEvent {\n [OptionalProps]?: 'processedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'provider_key', type: 'text' })\n providerKey!: string\n\n @Property({ name: 'idempotency_key', type: 'text' })\n idempotencyKey!: string\n\n @Property({ name: 'event_type', type: 'text' })\n eventType!: string\n\n @Property({ name: 'organization_id', type: 'uuid' })\n organizationId!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'processed_at', type: Date, onCreate: () => new Date() })\n processedAt: Date = new Date()\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { OptionalProps } from '@mikro-orm/core'\nimport { Entity, Index, PrimaryKey, Property, Unique } from '@mikro-orm/decorators/legacy'\n\n@Entity({ tableName: 'gateway_transactions' })\n@Index({ properties: ['paymentId', 'organizationId', 'tenantId'] })\n@Index({ properties: ['providerKey', 'providerSessionId', 'organizationId'] })\n@Index({ properties: ['organizationId', 'tenantId', 'unifiedStatus'] })\nexport class GatewayTransaction {\n [OptionalProps]?: 'unifiedStatus' | 'gatewayStatus' | 'providerSessionId' | 'gatewayPaymentId' | 'gatewayRefundId' | 'redirectUrl' | 'clientSecret' | 'gatewayMetadata' | 'webhookLog' | 'lastWebhookAt' | 'lastPolledAt' | 'expiresAt' | 'createdAt' | 'updatedAt' | 'deletedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'payment_id', type: 'uuid' })\n paymentId!: string\n\n @Property({ name: 'provider_key', type: 'text' })\n providerKey!: string\n\n @Property({ name: 'provider_session_id', type: 'text', nullable: true })\n providerSessionId?: string | null\n\n @Property({ name: 'gateway_payment_id', type: 'text', nullable: true })\n gatewayPaymentId?: string | null\n\n @Property({ name: 'gateway_refund_id', type: 'text', nullable: true })\n gatewayRefundId?: string | null\n\n @Property({ name: 'unified_status', type: 'text' })\n unifiedStatus: string = 'pending'\n\n @Property({ name: 'gateway_status', type: 'text', nullable: true })\n gatewayStatus?: string | null\n\n @Property({ name: 'redirect_url', type: 'text', nullable: true })\n redirectUrl?: string | null\n\n @Property({ name: 'client_secret', type: 'text', nullable: true })\n clientSecret?: string | null\n\n @Property({ name: 'amount', type: 'numeric', precision: 18, scale: 4 })\n amount!: string\n\n @Property({ name: 'currency_code', type: 'text' })\n currencyCode!: string\n\n @Property({ name: 'gateway_metadata', type: 'jsonb', nullable: true })\n gatewayMetadata?: Record<string, unknown> | null\n\n @Property({ name: 'webhook_log', type: 'jsonb', nullable: true })\n webhookLog?: Array<{ eventType: string; receivedAt: string; idempotencyKey: string; unifiedStatus: string; processed: boolean }> | null\n\n @Property({ name: 'last_webhook_at', type: Date, nullable: true })\n lastWebhookAt?: Date | null\n\n @Property({ name: 'last_polled_at', type: Date, nullable: true })\n lastPolledAt?: Date | null\n\n @Property({ name: 'expires_at', type: Date, nullable: true })\n expiresAt?: Date | null\n\n @Property({ name: 'organization_id', type: 'uuid' })\n organizationId!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'gateway_payment_operations' })\n@Unique({\n name: 'gateway_payment_operations_scope_operation_unique',\n properties: ['operationId', 'organizationId', 'tenantId'],\n})\n@Index({ properties: ['transactionId', 'operationType', 'organizationId', 'tenantId'] })\n@Index({ properties: ['status', 'leaseExpiresAt'] })\nexport class GatewayPaymentOperation {\n [OptionalProps]?: 'status' | 'attemptCount' | 'result' | 'leaseExpiresAt' | 'createdAt' | 'updatedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'operation_id', type: 'text' })\n operationId!: string\n\n @Property({ name: 'transaction_id', type: 'uuid' })\n transactionId!: string\n\n @Property({ name: 'operation_type', type: 'text' })\n operationType!: string\n\n @Property({ name: 'provider_key', type: 'text' })\n providerKey!: string\n\n @Property({ name: 'request_hash', type: 'text' })\n requestHash!: string\n\n @Property({ name: 'provider_idempotency_key', type: 'text' })\n providerIdempotencyKey!: string\n\n @Property({ name: 'status', type: 'text' })\n status: string = 'in_progress'\n\n @Property({ name: 'attempt_token', type: 'text' })\n attemptToken!: string\n\n @Property({ name: 'attempt_count', type: 'integer' })\n attemptCount: number = 1\n\n @Property({ name: 'result', type: 'jsonb', nullable: true })\n result?: Record<string, unknown> | null\n\n @Property({ name: 'lease_expires_at', type: Date, nullable: true })\n leaseExpiresAt?: Date | null\n\n @Property({ name: 'organization_id', type: 'uuid' })\n organizationId!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onCreate: () => new Date(), onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n}\n\n@Entity({ tableName: 'gateway_session_initializations' })\n@Unique({\n name: 'gateway_session_initializations_scope_operation_unique',\n properties: ['operationKey', 'providerKey', 'organizationId', 'tenantId'],\n})\nexport class GatewaySessionInitialization {\n [OptionalProps]?: 'claimToken' | 'claimedAt' | 'gatewayTransactionId' | 'createdAt' | 'updatedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'operation_key', type: 'text' })\n operationKey!: string\n\n @Property({ name: 'provider_key', type: 'text' })\n providerKey!: string\n\n @Property({ name: 'claim_token', type: 'uuid', nullable: true })\n claimToken?: string | null\n\n @Property({ name: 'claimed_at', type: Date, nullable: true })\n claimedAt?: Date | null\n\n @Property({ name: 'gateway_transaction_id', type: 'uuid', nullable: true })\n gatewayTransactionId?: string | null\n\n @Property({ name: 'organization_id', type: 'uuid' })\n organizationId!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onCreate: () => new Date(), onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n}\n\n@Entity({ tableName: 'gateway_webhook_events' })\n@Unique({\n name: 'gateway_webhook_events_idempotency_unique',\n properties: ['idempotencyKey', 'providerKey', 'organizationId', 'tenantId'],\n})\nexport class WebhookProcessedEvent {\n [OptionalProps]?: 'processedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'provider_key', type: 'text' })\n providerKey!: string\n\n @Property({ name: 'idempotency_key', type: 'text' })\n idempotencyKey!: string\n\n @Property({ name: 'event_type', type: 'text' })\n eventType!: string\n\n @Property({ name: 'organization_id', type: 'uuid' })\n organizationId!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'processed_at', type: Date, onCreate: () => new Date() })\n processedAt: Date = new Date()\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -30,16 +30,19 @@ const createSessionSchema = z.object({
|
|
|
30
30
|
});
|
|
31
31
|
const captureSchema = z.object({
|
|
32
32
|
transactionId: z.string().uuid(),
|
|
33
|
-
amount: z.number().positive().optional()
|
|
33
|
+
amount: z.number().positive().optional(),
|
|
34
|
+
operationId: z.string().trim().min(1).max(200).optional()
|
|
34
35
|
});
|
|
35
36
|
const refundSchema = z.object({
|
|
36
37
|
transactionId: z.string().uuid(),
|
|
37
38
|
amount: z.number().positive().optional(),
|
|
38
|
-
reason: z.string().max(200).optional()
|
|
39
|
+
reason: z.string().max(200).optional(),
|
|
40
|
+
operationId: z.string().trim().min(1).max(200).optional()
|
|
39
41
|
});
|
|
40
42
|
const cancelSchema = z.object({
|
|
41
43
|
transactionId: z.string().uuid(),
|
|
42
|
-
reason: z.string().max(200).optional()
|
|
44
|
+
reason: z.string().max(200).optional(),
|
|
45
|
+
operationId: z.string().trim().min(1).max(200).optional()
|
|
43
46
|
});
|
|
44
47
|
const getStatusSchema = z.object({
|
|
45
48
|
transactionId: z.string().uuid()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/payment_gateways/data/validators.ts"],
|
|
4
|
-
"sourcesContent": ["import { z } from 'zod'\n\nconst unifiedPaymentStatusSchema = z.enum([\n 'pending',\n 'authorized',\n 'captured',\n 'partially_captured',\n 'refunded',\n 'partially_refunded',\n 'cancelled',\n 'failed',\n 'expired',\n 'unknown',\n])\n\nexport const createSessionSchema = z.object({\n providerKey: z.string().min(1),\n paymentMethodId: z.string().uuid().optional(),\n orderId: z.string().uuid().optional(),\n amount: z.number().positive(),\n currencyCode: z.string().min(3).max(3),\n captureMethod: z.enum(['automatic', 'manual']).default('automatic'),\n description: z.string().max(500).optional(),\n successUrl: z.string().url().optional(),\n cancelUrl: z.string().url().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n presentation: z.object({\n mode: z.enum(['auto', 'embedded', 'redirect']).optional(),\n rendererKey: z.string().min(1).optional(),\n rendererSettings: z.record(z.string(), z.unknown()).optional(),\n }).optional(),\n})\n\nexport type CreateSessionPayload = z.infer<typeof createSessionSchema>\n\nexport const captureSchema = z.object({\n transactionId: z.string().uuid(),\n amount: z.number().positive().optional(),\n})\n\nexport type CapturePayload = z.infer<typeof captureSchema>\n\nexport const refundSchema = z.object({\n transactionId: z.string().uuid(),\n amount: z.number().positive().optional(),\n reason: z.string().max(200).optional(),\n})\n\nexport type RefundPayload = z.infer<typeof refundSchema>\n\nexport const cancelSchema = z.object({\n transactionId: z.string().uuid(),\n reason: z.string().max(200).optional(),\n})\n\nexport type CancelPayload = z.infer<typeof cancelSchema>\n\nexport const getStatusSchema = z.object({\n transactionId: z.string().uuid(),\n})\n\nexport type GetStatusPayload = z.infer<typeof getStatusSchema>\n\nexport const listTransactionsQuerySchema = z.object({\n page: z.coerce.number().int().min(1).default(1),\n pageSize: z.coerce.number().int().min(1).max(100).default(20),\n search: z.string().trim().max(200).optional(),\n providerKey: z.string().trim().min(1).max(100).optional(),\n status: unifiedPaymentStatusSchema.optional(),\n})\n\nexport type ListTransactionsQuery = z.infer<typeof listTransactionsQuerySchema>\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,SAAS;AAElB,MAAM,6BAA6B,EAAE,KAAK;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,MAAM,sBAAsB,EAAE,OAAO;AAAA,EAC1C,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,iBAAiB,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EAC5C,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EACpC,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,cAAc,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EACrC,eAAe,EAAE,KAAK,CAAC,aAAa,QAAQ,CAAC,EAAE,QAAQ,WAAW;AAAA,EAClE,aAAa,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAC1C,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACtC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACrC,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACrD,cAAc,EAAE,OAAO;AAAA,IACrB,MAAM,EAAE,KAAK,CAAC,QAAQ,YAAY,UAAU,CAAC,EAAE,SAAS;AAAA,IACxD,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,IACxC,kBAAkB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EAC/D,CAAC,EAAE,SAAS;AACd,CAAC;AAIM,MAAM,gBAAgB,EAAE,OAAO;AAAA,EACpC,eAAe,EAAE,OAAO,EAAE,KAAK;AAAA,EAC/B,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\n\nconst unifiedPaymentStatusSchema = z.enum([\n 'pending',\n 'authorized',\n 'captured',\n 'partially_captured',\n 'refunded',\n 'partially_refunded',\n 'cancelled',\n 'failed',\n 'expired',\n 'unknown',\n])\n\nexport const createSessionSchema = z.object({\n providerKey: z.string().min(1),\n paymentMethodId: z.string().uuid().optional(),\n orderId: z.string().uuid().optional(),\n amount: z.number().positive(),\n currencyCode: z.string().min(3).max(3),\n captureMethod: z.enum(['automatic', 'manual']).default('automatic'),\n description: z.string().max(500).optional(),\n successUrl: z.string().url().optional(),\n cancelUrl: z.string().url().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n presentation: z.object({\n mode: z.enum(['auto', 'embedded', 'redirect']).optional(),\n rendererKey: z.string().min(1).optional(),\n rendererSettings: z.record(z.string(), z.unknown()).optional(),\n }).optional(),\n})\n\nexport type CreateSessionPayload = z.infer<typeof createSessionSchema>\n\nexport const captureSchema = z.object({\n transactionId: z.string().uuid(),\n amount: z.number().positive().optional(),\n operationId: z.string().trim().min(1).max(200).optional(),\n})\n\nexport type CapturePayload = z.infer<typeof captureSchema>\n\nexport const refundSchema = z.object({\n transactionId: z.string().uuid(),\n amount: z.number().positive().optional(),\n reason: z.string().max(200).optional(),\n operationId: z.string().trim().min(1).max(200).optional(),\n})\n\nexport type RefundPayload = z.infer<typeof refundSchema>\n\nexport const cancelSchema = z.object({\n transactionId: z.string().uuid(),\n reason: z.string().max(200).optional(),\n operationId: z.string().trim().min(1).max(200).optional(),\n})\n\nexport type CancelPayload = z.infer<typeof cancelSchema>\n\nexport const getStatusSchema = z.object({\n transactionId: z.string().uuid(),\n})\n\nexport type GetStatusPayload = z.infer<typeof getStatusSchema>\n\nexport const listTransactionsQuerySchema = z.object({\n page: z.coerce.number().int().min(1).default(1),\n pageSize: z.coerce.number().int().min(1).max(100).default(20),\n search: z.string().trim().max(200).optional(),\n providerKey: z.string().trim().min(1).max(100).optional(),\n status: unifiedPaymentStatusSchema.optional(),\n})\n\nexport type ListTransactionsQuery = z.infer<typeof listTransactionsQuerySchema>\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,SAAS;AAElB,MAAM,6BAA6B,EAAE,KAAK;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,MAAM,sBAAsB,EAAE,OAAO;AAAA,EAC1C,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,iBAAiB,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EAC5C,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EACpC,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,cAAc,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EACrC,eAAe,EAAE,KAAK,CAAC,aAAa,QAAQ,CAAC,EAAE,QAAQ,WAAW;AAAA,EAClE,aAAa,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAC1C,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACtC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACrC,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACrD,cAAc,EAAE,OAAO;AAAA,IACrB,MAAM,EAAE,KAAK,CAAC,QAAQ,YAAY,UAAU,CAAC,EAAE,SAAS;AAAA,IACxD,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,IACxC,kBAAkB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EAC/D,CAAC,EAAE,SAAS;AACd,CAAC;AAIM,MAAM,gBAAgB,EAAE,OAAO;AAAA,EACpC,eAAe,EAAE,OAAO,EAAE,KAAK;AAAA,EAC/B,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACvC,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAC1D,CAAC;AAIM,MAAM,eAAe,EAAE,OAAO;AAAA,EACnC,eAAe,EAAE,OAAO,EAAE,KAAK;AAAA,EAC/B,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACvC,QAAQ,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACrC,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAC1D,CAAC;AAIM,MAAM,eAAe,EAAE,OAAO;AAAA,EACnC,eAAe,EAAE,OAAO,EAAE,KAAK;AAAA,EAC/B,QAAQ,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACrC,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAC1D,CAAC;AAIM,MAAM,kBAAkB,EAAE,OAAO;AAAA,EACtC,eAAe,EAAE,OAAO,EAAE,KAAK;AACjC,CAAC;AAIM,MAAM,8BAA8B,EAAE,OAAO;AAAA,EAClD,MAAM,EAAE,OAAO,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAAA,EAC9C,UAAU,EAAE,OAAO,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE;AAAA,EAC5D,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAC5C,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACxD,QAAQ,2BAA2B,SAAS;AAC9C,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -8,6 +8,11 @@ import { GatewaySessionInitialization, GatewayTransaction } from "../data/entiti
|
|
|
8
8
|
import { canApplyManualAction, isValidTransition } from "./status-machine.js";
|
|
9
9
|
import { emitPaymentGatewayEvent } from "../events.js";
|
|
10
10
|
import { readGatewayMetadata, readWebhookLog } from "./transaction-fields.js";
|
|
11
|
+
import {
|
|
12
|
+
completePaymentOperation,
|
|
13
|
+
failPaymentOperation,
|
|
14
|
+
preparePaymentOperation
|
|
15
|
+
} from "./payment-operation-idempotency.js";
|
|
11
16
|
import {
|
|
12
17
|
buildPaymentSessionOperationKey,
|
|
13
18
|
claimPaymentSessionInitialization,
|
|
@@ -27,6 +32,7 @@ function assertManualActionAllowed(action, transaction) {
|
|
|
27
32
|
function applyAdapterResultStatus(action, transaction, resultStatus) {
|
|
28
33
|
const current = transaction.unifiedStatus;
|
|
29
34
|
if (resultStatus === current) return false;
|
|
35
|
+
if (isValidTransition(resultStatus, current)) return false;
|
|
30
36
|
if (!isValidTransition(current, resultStatus)) {
|
|
31
37
|
throw conflict(
|
|
32
38
|
`Gateway returned status "${resultStatus}" which is not a valid transition from "${current}" for ${action}`
|
|
@@ -43,9 +49,9 @@ function createPaymentGatewayService(deps) {
|
|
|
43
49
|
deps.sessionClaimOptions?.heartbeatIntervalMs ?? Math.floor(claimStaleAfterMs / 3)
|
|
44
50
|
);
|
|
45
51
|
const claimPollIntervalMs = Math.max(1, deps.sessionClaimOptions?.pollIntervalMs ?? PAYMENT_SESSION_WAIT_INTERVAL_MS);
|
|
46
|
-
async function findTransactionOrThrow(transactionId, scope) {
|
|
52
|
+
async function findTransactionOrThrow(transactionId, scope, targetEm = em) {
|
|
47
53
|
const transaction = await findOneWithDecryption(
|
|
48
|
-
|
|
54
|
+
targetEm,
|
|
49
55
|
GatewayTransaction,
|
|
50
56
|
{
|
|
51
57
|
id: transactionId,
|
|
@@ -103,6 +109,64 @@ function createPaymentGatewayService(deps) {
|
|
|
103
109
|
const credentials = await integrationCredentialsService.resolve(integrationId, scope) ?? {};
|
|
104
110
|
return { adapter, credentials };
|
|
105
111
|
}
|
|
112
|
+
async function executeManualOperation(input) {
|
|
113
|
+
const transaction = await findTransactionOrThrow(input.transactionId, input.scope);
|
|
114
|
+
const prepared = await preparePaymentOperation({
|
|
115
|
+
em,
|
|
116
|
+
transactionId: transaction.id,
|
|
117
|
+
providerKey: transaction.providerKey,
|
|
118
|
+
action: input.action,
|
|
119
|
+
operationId: input.operationId,
|
|
120
|
+
payload: input.payload,
|
|
121
|
+
scope: input.scope,
|
|
122
|
+
assertInitialAllowed: () => assertManualActionAllowed(input.action, transaction)
|
|
123
|
+
});
|
|
124
|
+
if (prepared.kind === "completed") {
|
|
125
|
+
if (prepared.result.status !== transaction.unifiedStatus) {
|
|
126
|
+
throw conflict(
|
|
127
|
+
`Cannot replay ${input.action} because the payment status has changed since the operation completed`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
return prepared.result;
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
const { adapter, credentials } = await resolveAdapterAndCredentials(
|
|
134
|
+
transaction.providerKey,
|
|
135
|
+
{ organizationId: transaction.organizationId, tenantId: transaction.tenantId }
|
|
136
|
+
);
|
|
137
|
+
const result = await input.invoke({
|
|
138
|
+
adapter,
|
|
139
|
+
credentials,
|
|
140
|
+
transaction,
|
|
141
|
+
idempotencyKey: prepared.claim.providerIdempotencyKey
|
|
142
|
+
});
|
|
143
|
+
const statusChanged = await completePaymentOperation(
|
|
144
|
+
em,
|
|
145
|
+
prepared.claim,
|
|
146
|
+
result,
|
|
147
|
+
async (tx) => {
|
|
148
|
+
const current = await findTransactionOrThrow(input.transactionId, input.scope, tx);
|
|
149
|
+
const changed = applyAdapterResultStatus(input.action, current, result.status);
|
|
150
|
+
input.applyResult(current, result);
|
|
151
|
+
return changed;
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
if (statusChanged) {
|
|
155
|
+
await emitStatusEvent(result.status, {
|
|
156
|
+
transactionId: transaction.id,
|
|
157
|
+
paymentId: transaction.paymentId,
|
|
158
|
+
providerKey: transaction.providerKey,
|
|
159
|
+
organizationId: transaction.organizationId,
|
|
160
|
+
tenantId: transaction.tenantId
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
await input.afterCommit(transaction, result);
|
|
164
|
+
return result;
|
|
165
|
+
} catch (error) {
|
|
166
|
+
await Promise.allSettled([failPaymentOperation(em, prepared.claim)]);
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
106
170
|
function createGatewayTransaction(manager, input, session, id) {
|
|
107
171
|
const data = {
|
|
108
172
|
paymentId: input.paymentId,
|
|
@@ -283,120 +347,90 @@ function createPaymentGatewayService(deps) {
|
|
|
283
347
|
return { transaction, session };
|
|
284
348
|
}
|
|
285
349
|
},
|
|
286
|
-
async capturePayment(transactionId, amount, scope) {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
{
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
350
|
+
async capturePayment(transactionId, amount, scope, operationId) {
|
|
351
|
+
return executeManualOperation({
|
|
352
|
+
action: "capture",
|
|
353
|
+
transactionId,
|
|
354
|
+
operationId,
|
|
355
|
+
payload: { amount: amount ?? null },
|
|
356
|
+
scope,
|
|
357
|
+
invoke: ({ adapter, credentials, transaction, idempotencyKey }) => adapter.capture({
|
|
358
|
+
sessionId: readProviderSessionId(transaction),
|
|
359
|
+
amount,
|
|
360
|
+
credentials,
|
|
361
|
+
idempotencyKey
|
|
362
|
+
}),
|
|
363
|
+
applyResult: (transaction, result) => {
|
|
364
|
+
transaction.gatewayMetadata = {
|
|
365
|
+
...readGatewayMetadata(transaction.gatewayMetadata),
|
|
366
|
+
captureResult: result.providerData
|
|
367
|
+
};
|
|
368
|
+
},
|
|
369
|
+
afterCommit: (transaction, result) => writeTransactionLog(
|
|
370
|
+
transaction.providerKey,
|
|
371
|
+
{ organizationId: transaction.organizationId, tenantId: transaction.tenantId },
|
|
372
|
+
transaction.id,
|
|
373
|
+
"info",
|
|
374
|
+
"Payment captured",
|
|
375
|
+
{ amount: amount ?? null, status: result.status, capturedAmount: result.capturedAmount }
|
|
376
|
+
)
|
|
297
377
|
});
|
|
298
|
-
const statusChanged = applyAdapterResultStatus("capture", transaction, result.status);
|
|
299
|
-
transaction.gatewayMetadata = { ...readGatewayMetadata(transaction.gatewayMetadata), captureResult: result.providerData };
|
|
300
|
-
await em.flush();
|
|
301
|
-
if (statusChanged) {
|
|
302
|
-
await emitStatusEvent(result.status, {
|
|
303
|
-
transactionId: transaction.id,
|
|
304
|
-
paymentId: transaction.paymentId,
|
|
305
|
-
providerKey: transaction.providerKey,
|
|
306
|
-
organizationId: transaction.organizationId,
|
|
307
|
-
tenantId: transaction.tenantId
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
|
-
await writeTransactionLog(
|
|
311
|
-
transaction.providerKey,
|
|
312
|
-
{ organizationId: transaction.organizationId, tenantId: transaction.tenantId },
|
|
313
|
-
transaction.id,
|
|
314
|
-
"info",
|
|
315
|
-
"Payment captured",
|
|
316
|
-
{
|
|
317
|
-
amount: amount ?? null,
|
|
318
|
-
status: result.status,
|
|
319
|
-
capturedAmount: result.capturedAmount
|
|
320
|
-
}
|
|
321
|
-
);
|
|
322
|
-
return result;
|
|
323
378
|
},
|
|
324
|
-
async refundPayment(transactionId, amount, reason, scope) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
{
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
379
|
+
async refundPayment(transactionId, amount, reason, scope, operationId) {
|
|
380
|
+
return executeManualOperation({
|
|
381
|
+
action: "refund",
|
|
382
|
+
transactionId,
|
|
383
|
+
operationId,
|
|
384
|
+
payload: { amount: amount ?? null, reason: reason ?? null },
|
|
385
|
+
scope,
|
|
386
|
+
invoke: ({ adapter, credentials, transaction, idempotencyKey }) => adapter.refund({
|
|
387
|
+
sessionId: readProviderSessionId(transaction),
|
|
388
|
+
amount,
|
|
389
|
+
reason,
|
|
390
|
+
credentials,
|
|
391
|
+
idempotencyKey
|
|
392
|
+
}),
|
|
393
|
+
applyResult: (transaction, result) => {
|
|
394
|
+
transaction.gatewayRefundId = result.refundId;
|
|
395
|
+
transaction.gatewayMetadata = {
|
|
396
|
+
...readGatewayMetadata(transaction.gatewayMetadata),
|
|
397
|
+
refundResult: result.providerData
|
|
398
|
+
};
|
|
399
|
+
},
|
|
400
|
+
afterCommit: (transaction, result) => writeTransactionLog(
|
|
401
|
+
transaction.providerKey,
|
|
402
|
+
{ organizationId: transaction.organizationId, tenantId: transaction.tenantId },
|
|
403
|
+
transaction.id,
|
|
404
|
+
"info",
|
|
405
|
+
"Payment refunded",
|
|
406
|
+
{ amount: amount ?? null, reason: reason ?? null, status: result.status, refundId: result.refundId }
|
|
407
|
+
)
|
|
336
408
|
});
|
|
337
|
-
const statusChanged = applyAdapterResultStatus("refund", transaction, result.status);
|
|
338
|
-
transaction.gatewayRefundId = result.refundId;
|
|
339
|
-
transaction.gatewayMetadata = { ...readGatewayMetadata(transaction.gatewayMetadata), refundResult: result.providerData };
|
|
340
|
-
await em.flush();
|
|
341
|
-
if (statusChanged) {
|
|
342
|
-
await emitStatusEvent(result.status, {
|
|
343
|
-
transactionId: transaction.id,
|
|
344
|
-
paymentId: transaction.paymentId,
|
|
345
|
-
providerKey: transaction.providerKey,
|
|
346
|
-
organizationId: transaction.organizationId,
|
|
347
|
-
tenantId: transaction.tenantId
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
await writeTransactionLog(
|
|
351
|
-
transaction.providerKey,
|
|
352
|
-
{ organizationId: transaction.organizationId, tenantId: transaction.tenantId },
|
|
353
|
-
transaction.id,
|
|
354
|
-
"info",
|
|
355
|
-
"Payment refunded",
|
|
356
|
-
{
|
|
357
|
-
amount: amount ?? null,
|
|
358
|
-
reason: reason ?? null,
|
|
359
|
-
status: result.status,
|
|
360
|
-
refundId: result.refundId
|
|
361
|
-
}
|
|
362
|
-
);
|
|
363
|
-
return result;
|
|
364
409
|
},
|
|
365
|
-
async cancelPayment(transactionId, reason, scope) {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
{
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
410
|
+
async cancelPayment(transactionId, reason, scope, operationId) {
|
|
411
|
+
return executeManualOperation({
|
|
412
|
+
action: "cancel",
|
|
413
|
+
transactionId,
|
|
414
|
+
operationId,
|
|
415
|
+
payload: { reason: reason ?? null },
|
|
416
|
+
scope,
|
|
417
|
+
invoke: ({ adapter, credentials, transaction, idempotencyKey }) => adapter.cancel({
|
|
418
|
+
sessionId: readProviderSessionId(transaction),
|
|
419
|
+
reason,
|
|
420
|
+
credentials,
|
|
421
|
+
idempotencyKey
|
|
422
|
+
}),
|
|
423
|
+
applyResult: () => {
|
|
424
|
+
},
|
|
425
|
+
afterCommit: (transaction, result) => writeTransactionLog(
|
|
426
|
+
transaction.providerKey,
|
|
427
|
+
{ organizationId: transaction.organizationId, tenantId: transaction.tenantId },
|
|
428
|
+
transaction.id,
|
|
429
|
+
"info",
|
|
430
|
+
"Payment cancelled",
|
|
431
|
+
{ reason: reason ?? null, status: result.status }
|
|
432
|
+
)
|
|
376
433
|
});
|
|
377
|
-
const statusChanged = applyAdapterResultStatus("cancel", transaction, result.status);
|
|
378
|
-
await em.flush();
|
|
379
|
-
if (statusChanged) {
|
|
380
|
-
await emitStatusEvent(result.status, {
|
|
381
|
-
transactionId: transaction.id,
|
|
382
|
-
paymentId: transaction.paymentId,
|
|
383
|
-
providerKey: transaction.providerKey,
|
|
384
|
-
organizationId: transaction.organizationId,
|
|
385
|
-
tenantId: transaction.tenantId
|
|
386
|
-
});
|
|
387
|
-
}
|
|
388
|
-
await writeTransactionLog(
|
|
389
|
-
transaction.providerKey,
|
|
390
|
-
{ organizationId: transaction.organizationId, tenantId: transaction.tenantId },
|
|
391
|
-
transaction.id,
|
|
392
|
-
"info",
|
|
393
|
-
"Payment cancelled",
|
|
394
|
-
{
|
|
395
|
-
reason: reason ?? null,
|
|
396
|
-
status: result.status
|
|
397
|
-
}
|
|
398
|
-
);
|
|
399
|
-
return result;
|
|
400
434
|
},
|
|
401
435
|
async getPaymentStatus(transactionId, scope) {
|
|
402
436
|
const transaction = await findTransactionOrThrow(transactionId, scope);
|