@abhi1693/medusa-payment-razorpay 0.0.0-stage → 0.0.2
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/LICENSE +21 -0
- package/README.md +153 -2
- package/dist/amounts.d.ts +6 -0
- package/dist/amounts.js +30 -0
- package/dist/configuration.d.ts +12 -0
- package/dist/configuration.js +15 -0
- package/dist/financial-coordination.d.ts +11 -0
- package/dist/financial-coordination.js +35 -0
- package/dist/gateway-refund-pending-error.d.ts +5 -0
- package/dist/gateway-refund-pending-error.js +16 -0
- package/dist/gateway-refund-reconciliation-error.d.ts +5 -0
- package/dist/gateway-refund-reconciliation-error.js +17 -0
- package/dist/gateway.d.ts +46 -0
- package/dist/gateway.js +138 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +52 -0
- package/dist/logger.d.ts +18 -0
- package/dist/logger.js +46 -0
- package/dist/operator-configuration.d.ts +11 -0
- package/dist/operator-configuration.js +41 -0
- package/dist/operator-recovery-context.d.ts +5 -0
- package/dist/operator-recovery-context.js +6 -0
- package/dist/operator-recovery-required-error.d.ts +3 -0
- package/dist/operator-recovery-required-error.js +10 -0
- package/dist/operator-recovery.d.ts +28 -0
- package/dist/operator-recovery.js +326 -0
- package/dist/razorpay-refund-rejected-error.d.ts +5 -0
- package/dist/razorpay-refund-rejected-error.js +12 -0
- package/dist/reconciliation.d.ts +34 -0
- package/dist/reconciliation.js +190 -0
- package/dist/records.d.ts +2 -0
- package/dist/records.js +12 -0
- package/dist/refund-acknowledgement.d.ts +13 -0
- package/dist/refund-acknowledgement.js +32 -0
- package/dist/refund-import-context.d.ts +6 -0
- package/dist/refund-import-context.js +6 -0
- package/dist/refund-import.d.ts +31 -0
- package/dist/refund-import.js +447 -0
- package/dist/refund-observation.d.ts +43 -0
- package/dist/refund-observation.js +77 -0
- package/dist/refund-recovery-error.d.ts +3 -0
- package/dist/refund-recovery-error.js +10 -0
- package/dist/refund-recovery.d.ts +38 -0
- package/dist/refund-recovery.js +28 -0
- package/dist/scripts/refund-recovery.d.ts +10 -0
- package/dist/scripts/refund-recovery.js +66 -0
- package/dist/security.d.ts +3 -0
- package/dist/security.js +34 -0
- package/dist/service.d.ts +114 -0
- package/dist/service.js +426 -0
- package/docs/operations.md +115 -0
- package/docs/server-integration.md +151 -0
- package/package.json +74 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Abhimanyu Saharan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,154 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Medusa Razorpay
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/abhi1693/medusa-payment-razorpay/actions/workflows/ci.yaml)
|
|
4
|
+
|
|
5
|
+
[](https://docs.medusajs.com/)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://github.com/sponsors/abhi1693)
|
|
8
|
+
|
|
9
|
+
A Razorpay payment provider for Medusa v2, with verified checkout results, automatic-capture payments, full and partial refunds, and reusable server-side reconciliation helpers. Uses native Medusa payment sessions, payments, captures and refunds without additional models or a financial ledger.
|
|
10
|
+
|
|
11
|
+
**Supports INR with explicitly configured Razorpay test or live credentials.** Unsupported currencies and mode/key mismatches are rejected. Automatic capture must already be configured in the selected Razorpay account. Live-mode support is a configuration capability, not a claim that real-money processing or a deployment has been validated.
|
|
12
|
+
|
|
13
|
+
[Setup](#installation-and-configuration) · [Checkout](#storefront-checkout) · [Webhooks](#webhooks) · [Server integration](docs/server-integration.md) · [Operations](docs/operations.md)
|
|
14
|
+
|
|
15
|
+
## Supported payment lifecycle
|
|
16
|
+
|
|
17
|
+
| Capability | Behavior |
|
|
18
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
19
|
+
| Payment sessions | Creates a Razorpay order from the server-provided Medusa amount, with precise rupee-to-paise conversion and a native session association. |
|
|
20
|
+
| Checkout verification | Verifies the signature, fetched payment and order, amount, INR currency and session association before accepting payment. |
|
|
21
|
+
| Automatic capture | Requires captured gateway funds before authorization completes. Native capture verifies gateway state and never sends another capture request. |
|
|
22
|
+
| Failed attempts | Allows another attempt on the same order after the previous bound attempt has failed. Successful or in-progress associations cannot silently be replaced. |
|
|
23
|
+
| Cancellation | Cancels/deletes an unpaid session locally; rejects cancellation when gateway payment is authorized or captured. It does not cancel a Razorpay order or issue an implicit refund. |
|
|
24
|
+
| Refunds | Full and partial normal-speed refunds, minimum INR 1.00, with a stable native operation key sent through Razorpay's idempotent refund API. |
|
|
25
|
+
| Payment webhooks | Signed `payment.authorized` and `payment.captured` events re-fetch gateway state; native processing proceeds only after capture. |
|
|
26
|
+
| Refund observation | Signed refund events trigger authenticated current-state checks through optional application wiring. The optional importer records verified processed Dashboard and deferred native refunds in native accounting without sending funds again. Pending/failed refunds do not create accounting entries. |
|
|
27
|
+
|
|
28
|
+
The declared framework peer versions are **2.22.2 and 2.22.4**. Native application validation targets Medusa 2.22.2; package development uses 2.22.4. This repository provides a payment module provider and server helpers. Checkout UI, customer authorization, terms acceptance, order-completion policy and infrastructure belong to the consuming application.
|
|
29
|
+
|
|
30
|
+
## Installation and configuration
|
|
31
|
+
|
|
32
|
+
For source installation, use a reviewed full commit SHA and commit your application's lockfile:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
npm install 'git+https://github.com/abhi1693/medusa-payment-razorpay.git#<reviewed-full-commit-sha>'
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Git installation runs the package's TypeScript build through its `prepare` script. Your build environment needs Git, Node.js and the declared peer dependency. The repository's Docker toolchain uses Node.js 24.
|
|
39
|
+
|
|
40
|
+
Add the provider to your existing Payment Module configuration in `medusa-config.ts`:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
{
|
|
44
|
+
resolve: "@medusajs/medusa/payment",
|
|
45
|
+
options: {
|
|
46
|
+
providers: [
|
|
47
|
+
// Keep your other payment providers here.
|
|
48
|
+
{
|
|
49
|
+
resolve: "@abhi1693/medusa-payment-razorpay",
|
|
50
|
+
id: "razorpay",
|
|
51
|
+
options: {
|
|
52
|
+
mode: process.env.RAZORPAY_MODE,
|
|
53
|
+
key_id: process.env.RAZORPAY_KEY_ID,
|
|
54
|
+
key_secret: process.env.RAZORPAY_KEY_SECRET,
|
|
55
|
+
webhook_secret: process.env.RAZORPAY_WEBHOOK_SECRET,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Configure the backend's private environment:
|
|
64
|
+
|
|
65
|
+
```dotenv
|
|
66
|
+
RAZORPAY_MODE=test
|
|
67
|
+
RAZORPAY_KEY_ID=rzp_test_REPLACE_ME
|
|
68
|
+
RAZORPAY_KEY_SECRET=REPLACE_ME
|
|
69
|
+
RAZORPAY_WEBHOOK_SECRET=REPLACE_ME
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
These are placeholders. Never commit actual credentials or expose the secret or webhook secret to a frontend. The key ID is public checkout configuration. Set `mode` explicitly to `test` or `live`: the key ID must begin with the matching `rzp_test_` or `rzp_live_` prefix and a nonempty API secret is required. Missing/unknown modes, malformed IDs and mismatches fail before network access; the plugin never infers live mode from a key. This validates configuration shape, not whether the key/secret pair is valid at Razorpay.
|
|
73
|
+
|
|
74
|
+
For live configuration, use `RAZORPAY_MODE=live`, a matching live key ID and that environment's API and webhook secrets. **Live provider initialization requires a nonempty webhook secret.** Test mode may omit it for initial Admin setup, but webhook delivery always fails closed without a valid secret. Use separate deployments/data, credentials and webhook endpoints/secrets for test and live; do not switch an existing test database into live processing. See [account modes](docs/operations.md#account-modes).
|
|
75
|
+
|
|
76
|
+
Start the backend through your application's normal workflow. In **Admin → Settings → Regions → your region**, select the Razorpay payment provider. This registration produces provider ID **`pp_razorpay_razorpay`**. Registration alone does not associate it with a region. There is no enabled/disabled environment toggle and no custom Admin menu or plugin migration.
|
|
77
|
+
|
|
78
|
+
## Storefront checkout
|
|
79
|
+
|
|
80
|
+
1. Create/select a native Medusa payment session using `pp_razorpay_razorpay`.
|
|
81
|
+
2. Initialize Razorpay Checkout using the session's public `key_id`, `order_id`, `amount` (paise) and `currency` (`INR`).
|
|
82
|
+
3. Submit `razorpay_order_id`, `razorpay_payment_id` and `razorpay_signature` through Medusa's Store payment-session client-data endpoint (`data.client`). Keep the stored server session fields authoritative.
|
|
83
|
+
4. Complete the cart through your backend's normal ownership, cart-total and acceptance checks. While automatic capture is pending, wait/reconcile rather than treating authorization as a completed payment.
|
|
84
|
+
|
|
85
|
+
The provider includes no checkout widget and makes no blanket promise about individual Razorpay payment methods. Available methods depend on the merchant account and Checkout configuration. Enforce application rules on the server: native payment webhooks may complete carts without the browser returning.
|
|
86
|
+
|
|
87
|
+
## Webhooks
|
|
88
|
+
|
|
89
|
+
For the example registration above, use your **backend's public HTTPS origin** with:
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
/hooks/payment/razorpay_razorpay
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Subscribe to `payment.authorized` and `payment.captured` in the matching Razorpay account and mode. Preserve the exact raw request bytes and `x-razorpay-signature` header. The provider verifies HMAC signatures and fetches current gateway state, making repeated and out-of-order notifications safe to re-evaluate. `payment.failed` and other unsupported payment events are ignored; they do not invalidate a later checkout attempt.
|
|
96
|
+
|
|
97
|
+
For refund observation, also subscribe to `refund.created`, `refund.processed`, `refund.failed` and `refund.speed_changed`, and wire the exported server helpers into an application subscriber. These events require an application subscriber calling the importer; provider registration alone does not import accounting. A speed change updates informational observations only; it never means settlement or initiates a refund.
|
|
98
|
+
|
|
99
|
+
See [server integration](docs/server-integration.md) for the helper contract, shared locking hook and subscriber requirements. Use durable Medusa event infrastructure and monitor failed jobs; HTTP acknowledgement is not proof of successful reconciliation.
|
|
100
|
+
|
|
101
|
+
## Refunds and reconciliation
|
|
102
|
+
|
|
103
|
+
Initiate refunds through Medusa's native refund workflow and preserve the operation identity. A synchronously processed response completes normally. A pending gateway response returns an explanatory conflict and remains outside successful native refund accounting. Wire the signed refund subscriber below: a later processed event imports one successful native refund, while a later failed event creates no successful refund accounting. The original native failed attempt remains as audit evidence; it does not mean the gateway request failed. Do not issue a new operation merely to retry a pending request. `last_refund_initial_status` is an immutable processed-response snapshot, not proof of bank receipt.
|
|
104
|
+
|
|
105
|
+
The exported reconciliation helpers compare authenticated gateway payment/order/refund information with native records. The read-only report helpers never change records. The optional importer uses native financial APIs only for individually verified processed Dashboard and deferred native refunds and rejects ambiguous associations. Review discrepancies before retrying an uncertain request. Applications can supply a `refund_guard` and a common distributed lock covering the session and its associated order to coordinate refund execution, observation and order completion.
|
|
106
|
+
|
|
107
|
+
Read [operations and validation](docs/operations.md) for pending/failed refund handling, uncertain outcomes, monitoring and test limits. The exported `assessRazorpayRefundRecovery` and `recoverRazorpayRefund` helpers provide a controlled operator path for supported processed-refund imports, with reviewed snapshots, application-enforced maintenance controls and post-recovery accounting checks. Original pending reservations remain quarantined. Known incomplete canonical accounting requires the operator path; automatic takeover scheduling is disabled.
|
|
108
|
+
|
|
109
|
+
## Logging
|
|
110
|
+
|
|
111
|
+
Set provider option `log_level` to `debug`, `info` (default), `warning`, `error`, `critical`, or `none`. Thresholds include the selected level and higher severities. `none` emits no plugin log records. JSON records contain `level`, a clear `message`, and `context`. The simple shared logger uses Medusa's injected logger, with a console fallback. Warning uses the `warn` sink; critical uses `error` while retaining its JSON severity.
|
|
112
|
+
|
|
113
|
+
All API calls use one typed HTTP client with `get`, `post`, `put`, `patch` and `delete`. Authentication, timeout, parsing, and request/response logging live in its single executor. Callers do not add HTTP logging code or classifications. Request context includes the complete supplied API path (including pagination), method, a local correlation UUID and timing. Paths contain opaque gateway resource IDs; these are included as requested.
|
|
114
|
+
|
|
115
|
+
Debug records receive the complete request body and provider response, including unknown response keys. There is no provider-field extraction or event-schema framework. Authentication headers are never supplied to the logger. Redaction is intentionally not implemented for the current debugging stage. Raw debug bodies can contain personal or sensitive data. Restrict access and retention, and use test data. Keep live deployments at `info` or higher (or `none`); raw `debug` payloads are not suitable for routine live logging. Authentication headers and configured credentials are not intentionally added to log context; an upstream response or caller-supplied body can still contain sensitive values. Other levels omit request/response bodies.
|
|
116
|
+
|
|
117
|
+
## Common API client
|
|
118
|
+
|
|
119
|
+
`RazorpayGateway` takes a named `GatewayOptions` object with explicit `mode`, matching credentials, optional Medusa logger, log level, timeout and injectable `fetch` for isolated testing. The base host is fixed, redirects are rejected, authentication cannot be overridden by custom headers, and timeout is bounded at 15 seconds. Reconciliation uses its GET-only adapter with a 30-second aggregate deadline. The compatibility `request` method delegates to the same executor; plugin internals use explicit verbs.
|
|
120
|
+
|
|
121
|
+
`GatewayRequestError` has typed method, failure kind and optional HTTP status. Transport failures are generic; response errors remain distinct from HTTP errors. No HTTP method retries automatically. `reconciliation_required` is a precaution on failed writes, not proof of a mismatch or a completed reconciliation. GET failures set it false. A successful HTTP response does not establish refund settlement.
|
|
122
|
+
|
|
123
|
+
## Development
|
|
124
|
+
|
|
125
|
+
Run project commands through Docker Compose:
|
|
126
|
+
|
|
127
|
+
```sh
|
|
128
|
+
docker compose build tools
|
|
129
|
+
docker compose run --rm tools npm run format:check
|
|
130
|
+
docker compose run --rm tools npm run lint
|
|
131
|
+
docker compose run --rm tools npm run typecheck
|
|
132
|
+
docker compose run --rm tools npm test
|
|
133
|
+
docker compose run --rm tools npm run build
|
|
134
|
+
docker compose run --rm tools npm run package:check
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Prettier checks the repository, including documentation and configuration; `.editorconfig` and `.prettierrc.json` define the shared editor style. Generated files, private environment files and local scratch files are ignored. To apply formatting to the checkout, use the tools container with the repository mounted at `/plugin` and its image dependencies available, or the Compose bootstrap service after installing development dependencies.
|
|
138
|
+
|
|
139
|
+
Typecheck validates both the published source and unit tests. The test project matches Vitest's ESM resolution; malformed runtime fixture values remain explicit test boundaries. The scripts under `tests/native` are consuming-Medusa integration fixtures and resolve/run inside that application's isolated test environment, not the standalone unit-test project.
|
|
140
|
+
|
|
141
|
+
The GitHub workflow runs formatting, lint, typecheck and build as separately visible checks, reusing the Node CI and security workflows from `abhi1693/actions@v1`. Each unit suite runs independently in its own matrix job and uploads JUnit XML. Reproduce a selected suite locally with `docker compose run --rm tools npm test -- tests/http-client.test.ts`. These self-contained suites use mocked gateway/service fixtures and do not perform gateway transactions. Hosted results and consuming-application integration evidence remain separate from local unit checks.
|
|
142
|
+
|
|
143
|
+
## Rejected refund requests
|
|
144
|
+
|
|
145
|
+
A refund POST rejected with HTTP 400 raises `RazorpayRefundRejectedError`
|
|
146
|
+
(`invalid_data`, code `razorpay_refund_rejected`). Medusa Admin can show its
|
|
147
|
+
actionable message instead of a generic server error. The message asks operators
|
|
148
|
+
to verify the refund status and available balance before retrying. HTTP 400 alone does not establish insufficient balance.
|
|
149
|
+
Transport failures and other uncertain responses retain reconciliation handling;
|
|
150
|
+
the provider never retries a refund automatically.
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
[MIT](LICENSE) © Abhimanyu Saharan.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Exact INR accounting conversion; positivity is a caller-specific constraint. */
|
|
2
|
+
export declare function inrMinorUnits(value: unknown, { allowNegative }?: {
|
|
3
|
+
allowNegative?: boolean;
|
|
4
|
+
}): number;
|
|
5
|
+
/** Use a decimal string at Medusa BigNumberValue boundaries, never float division. */
|
|
6
|
+
export declare function inrMajorUnits(value: number): string;
|
package/dist/amounts.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.inrMinorUnits = inrMinorUnits;
|
|
4
|
+
exports.inrMajorUnits = inrMajorUnits;
|
|
5
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
6
|
+
/** Exact INR accounting conversion; positivity is a caller-specific constraint. */
|
|
7
|
+
function inrMinorUnits(value, { allowNegative = false } = {}) {
|
|
8
|
+
if (value === undefined || value === null)
|
|
9
|
+
throw new Error("Invalid INR amount");
|
|
10
|
+
const decimal = new utils_1.BigNumber(value).bigNumber;
|
|
11
|
+
if (!decimal || !decimal.isFinite())
|
|
12
|
+
throw new Error("Invalid INR amount");
|
|
13
|
+
const minor = decimal.multipliedBy(100);
|
|
14
|
+
if (!minor.isInteger() || (!allowNegative && minor.lt(0)))
|
|
15
|
+
throw new Error("Invalid INR amount");
|
|
16
|
+
if (minor.abs().gt(Number.MAX_SAFE_INTEGER))
|
|
17
|
+
throw new Error("INR amount exceeds supported range");
|
|
18
|
+
return minor.toNumber();
|
|
19
|
+
}
|
|
20
|
+
/** Use a decimal string at Medusa BigNumberValue boundaries, never float division. */
|
|
21
|
+
function inrMajorUnits(value) {
|
|
22
|
+
if (!Number.isSafeInteger(value))
|
|
23
|
+
throw new Error("Invalid INR minor amount");
|
|
24
|
+
const negative = value < 0;
|
|
25
|
+
const amount = BigInt(Math.abs(value));
|
|
26
|
+
return ((negative ? "-" : "") +
|
|
27
|
+
amount / 100n +
|
|
28
|
+
"." +
|
|
29
|
+
String(amount % 100n).padStart(2, "0"));
|
|
30
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type RazorpayMode = "test" | "live";
|
|
2
|
+
export type RazorpayCredentials = {
|
|
3
|
+
mode: RazorpayMode;
|
|
4
|
+
key_id: string;
|
|
5
|
+
key_secret: string;
|
|
6
|
+
};
|
|
7
|
+
/** Require an explicit account mode; never infer live access from a key. */
|
|
8
|
+
export declare function validateRazorpayCredentials<T extends {
|
|
9
|
+
mode?: unknown;
|
|
10
|
+
key_id?: unknown;
|
|
11
|
+
key_secret?: unknown;
|
|
12
|
+
}>(options: T): asserts options is T & RazorpayCredentials;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateRazorpayCredentials = validateRazorpayCredentials;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
/** Require an explicit account mode; never infer live access from a key. */
|
|
6
|
+
function validateRazorpayCredentials(options) {
|
|
7
|
+
if (options.mode !== "test" && options.mode !== "live")
|
|
8
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Razorpay mode must be explicitly set to test or live");
|
|
9
|
+
if (typeof options.key_id !== "string" ||
|
|
10
|
+
options.key_id !== options.key_id.trim() ||
|
|
11
|
+
!new RegExp(`^rzp_${options.mode}_[A-Za-z0-9]+$`).test(options.key_id))
|
|
12
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Razorpay key ID must match the configured mode");
|
|
13
|
+
if (typeof options.key_secret !== "string" || !options.key_secret.trim())
|
|
14
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Razorpay API secret must be configured privately");
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type FinancialCoordinator = <T>(sessions: string[], work: () => Promise<T>) => Promise<T>;
|
|
2
|
+
export type SessionOrderAssociation = {
|
|
3
|
+
session_id: string;
|
|
4
|
+
order_id: string | null;
|
|
5
|
+
};
|
|
6
|
+
export type FinancialCoordinationDependencies = {
|
|
7
|
+
resolve: (sessions: string[]) => Promise<SessionOrderAssociation[]>;
|
|
8
|
+
execute: <T>(keys: string[], work: () => Promise<T>) => Promise<T>;
|
|
9
|
+
};
|
|
10
|
+
/** Trusted server resolver and shared distributed locking are supplied by the app. */
|
|
11
|
+
export declare function createRazorpayCoordinator(dependencies: FinancialCoordinationDependencies): FinancialCoordinator;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRazorpayCoordinator = createRazorpayCoordinator;
|
|
4
|
+
/** Trusted server resolver and shared distributed locking are supplied by the app. */
|
|
5
|
+
function createRazorpayCoordinator(dependencies) {
|
|
6
|
+
const associations = async (sessions) => {
|
|
7
|
+
const rows = await dependencies.resolve([...sessions]);
|
|
8
|
+
if (rows.length !== sessions.length ||
|
|
9
|
+
new Set(rows.map((row) => row.session_id)).size !== rows.length ||
|
|
10
|
+
rows.some((row) => !sessions.includes(row.session_id) ||
|
|
11
|
+
(row.order_id !== null && !/^order_[A-Za-z0-9]+$/.test(row.order_id))))
|
|
12
|
+
throw new Error("Incomplete or invalid financial order association");
|
|
13
|
+
return rows
|
|
14
|
+
.map(({ session_id, order_id }) => ({ session_id, order_id }))
|
|
15
|
+
.sort((a, b) => a.session_id.localeCompare(b.session_id));
|
|
16
|
+
};
|
|
17
|
+
return async (input, work) => {
|
|
18
|
+
const sessions = [...new Set(input)].sort();
|
|
19
|
+
if (!sessions.length ||
|
|
20
|
+
sessions.some((id) => !/^payses_[A-Za-z0-9]+$/.test(id)))
|
|
21
|
+
throw new Error("Invalid financial coordination identity");
|
|
22
|
+
const before = await associations(sessions);
|
|
23
|
+
const keys = [
|
|
24
|
+
...new Set(before.flatMap(({ session_id, order_id }) => [
|
|
25
|
+
"razorpay:session:" + session_id,
|
|
26
|
+
...(order_id ? ["razorpay:order:" + order_id] : []),
|
|
27
|
+
])),
|
|
28
|
+
].sort();
|
|
29
|
+
return dependencies.execute(keys, async () => {
|
|
30
|
+
if (JSON.stringify(before) !== JSON.stringify(await associations(sessions)))
|
|
31
|
+
throw new Error("Financial order association changed; retry coordination");
|
|
32
|
+
return work();
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GatewayRefundPendingError = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
// A gateway request exists, but native financial accounting must await processing.
|
|
6
|
+
class GatewayRefundPendingError extends utils_1.MedusaError {
|
|
7
|
+
gateway_refund_id;
|
|
8
|
+
constructor(gateway_refund_id) {
|
|
9
|
+
super(utils_1.MedusaError.Types.CONFLICT, "Razorpay refund " +
|
|
10
|
+
gateway_refund_id +
|
|
11
|
+
" is pending. Do not issue another refund; signed reconciliation will record it after processing.");
|
|
12
|
+
this.gateway_refund_id = gateway_refund_id;
|
|
13
|
+
this.name = "GatewayRefundPendingError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.GatewayRefundPendingError = GatewayRefundPendingError;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GatewayRefundReconciliationError = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
// Existing gateway funds must be adopted by the coordinated native importer,
|
|
6
|
+
// never by restoring a second native attempt after canonical import.
|
|
7
|
+
class GatewayRefundReconciliationError extends utils_1.MedusaError {
|
|
8
|
+
gateway_refund_id;
|
|
9
|
+
constructor(gateway_refund_id) {
|
|
10
|
+
super(utils_1.MedusaError.Types.CONFLICT, "Razorpay refund " +
|
|
11
|
+
gateway_refund_id +
|
|
12
|
+
" is already processed. Await signed reconciliation; do not issue another refund.");
|
|
13
|
+
this.gateway_refund_id = gateway_refund_id;
|
|
14
|
+
this.name = "GatewayRefundReconciliationError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.GatewayRefundReconciliationError = GatewayRefundReconciliationError;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type RazorpayCredentials } from "./configuration";
|
|
2
|
+
import { type LoggerSink, type LogLevel } from "./logger";
|
|
3
|
+
export interface Entity {
|
|
4
|
+
id: string;
|
|
5
|
+
amount: number;
|
|
6
|
+
currency: string;
|
|
7
|
+
status: string;
|
|
8
|
+
order_id?: string;
|
|
9
|
+
payment_id?: string;
|
|
10
|
+
amount_refunded?: number;
|
|
11
|
+
notes?: Record<string, string>;
|
|
12
|
+
receipt?: string;
|
|
13
|
+
}
|
|
14
|
+
export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
15
|
+
export type GatewayFailureKind = "http" | "transport" | "response";
|
|
16
|
+
export interface Gateway {
|
|
17
|
+
get<T>(path: string, timeoutMs?: number): Promise<T>;
|
|
18
|
+
post<T>(path: string, body: unknown, headers?: Record<string, string>): Promise<T>;
|
|
19
|
+
}
|
|
20
|
+
export interface GatewayOptions extends RazorpayCredentials {
|
|
21
|
+
logger?: LoggerSink;
|
|
22
|
+
log_level?: LogLevel;
|
|
23
|
+
fetch?: typeof fetch;
|
|
24
|
+
timeout_ms?: number;
|
|
25
|
+
}
|
|
26
|
+
export declare class GatewayRequestError extends Error {
|
|
27
|
+
readonly method: HttpMethod;
|
|
28
|
+
readonly kind: GatewayFailureKind;
|
|
29
|
+
readonly status?: number | undefined;
|
|
30
|
+
constructor(message: string, method: HttpMethod, kind: GatewayFailureKind, status?: number | undefined);
|
|
31
|
+
}
|
|
32
|
+
export declare class RazorpayGateway implements Gateway {
|
|
33
|
+
private readonly authorization;
|
|
34
|
+
private readonly logger;
|
|
35
|
+
private readonly transport;
|
|
36
|
+
private readonly timeoutMs;
|
|
37
|
+
constructor(options: GatewayOptions);
|
|
38
|
+
get<T>(path: string, timeoutMs?: number): Promise<T>;
|
|
39
|
+
post<T>(path: string, body: unknown, headers?: Record<string, string>): Promise<T>;
|
|
40
|
+
put<T>(path: string, body: unknown, headers?: Record<string, string>): Promise<T>;
|
|
41
|
+
patch<T>(path: string, body: unknown, headers?: Record<string, string>): Promise<T>;
|
|
42
|
+
delete<T>(path: string, headers?: Record<string, string>): Promise<T>;
|
|
43
|
+
/** Compatibility adapter; plugin internals use explicit HTTP verbs. */
|
|
44
|
+
request<T>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
45
|
+
private execute;
|
|
46
|
+
}
|
package/dist/gateway.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RazorpayGateway = exports.GatewayRequestError = void 0;
|
|
4
|
+
const configuration_1 = require("./configuration");
|
|
5
|
+
const node_crypto_1 = require("node:crypto");
|
|
6
|
+
const logger_1 = require("./logger");
|
|
7
|
+
class GatewayRequestError extends Error {
|
|
8
|
+
method;
|
|
9
|
+
kind;
|
|
10
|
+
status;
|
|
11
|
+
constructor(message, method, kind, status) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.method = method;
|
|
14
|
+
this.kind = kind;
|
|
15
|
+
this.status = status;
|
|
16
|
+
this.name = "GatewayRequestError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.GatewayRequestError = GatewayRequestError;
|
|
20
|
+
class RazorpayGateway {
|
|
21
|
+
authorization;
|
|
22
|
+
logger;
|
|
23
|
+
transport;
|
|
24
|
+
timeoutMs;
|
|
25
|
+
constructor(options) {
|
|
26
|
+
(0, configuration_1.validateRazorpayCredentials)(options);
|
|
27
|
+
this.timeoutMs = options.timeout_ms ?? 15000;
|
|
28
|
+
if (!Number.isSafeInteger(this.timeoutMs) ||
|
|
29
|
+
this.timeoutMs < 1 ||
|
|
30
|
+
this.timeoutMs > 15000)
|
|
31
|
+
throw new Error("Invalid Razorpay request timeout");
|
|
32
|
+
this.authorization =
|
|
33
|
+
"Basic " +
|
|
34
|
+
Buffer.from(options.key_id + ":" + options.key_secret).toString("base64");
|
|
35
|
+
this.logger = (0, logger_1.createLogger)({
|
|
36
|
+
sink: options.logger,
|
|
37
|
+
level: options.log_level,
|
|
38
|
+
});
|
|
39
|
+
this.transport = options.fetch || ((...args) => globalThis.fetch(...args));
|
|
40
|
+
}
|
|
41
|
+
get(path, timeoutMs = this.timeoutMs) {
|
|
42
|
+
return this.execute("GET", path, undefined, {}, timeoutMs);
|
|
43
|
+
}
|
|
44
|
+
post(path, body, headers = {}) {
|
|
45
|
+
return this.execute("POST", path, body, headers);
|
|
46
|
+
}
|
|
47
|
+
put(path, body, headers = {}) {
|
|
48
|
+
return this.execute("PUT", path, body, headers);
|
|
49
|
+
}
|
|
50
|
+
patch(path, body, headers = {}) {
|
|
51
|
+
return this.execute("PATCH", path, body, headers);
|
|
52
|
+
}
|
|
53
|
+
delete(path, headers = {}) {
|
|
54
|
+
return this.execute("DELETE", path, undefined, headers);
|
|
55
|
+
}
|
|
56
|
+
/** Compatibility adapter; plugin internals use explicit HTTP verbs. */
|
|
57
|
+
request(path, body, headers = {}) {
|
|
58
|
+
return body === undefined
|
|
59
|
+
? this.get(path)
|
|
60
|
+
: this.post(path, body, headers);
|
|
61
|
+
}
|
|
62
|
+
async execute(method, path, body, headers = {}, timeoutMs = this.timeoutMs) {
|
|
63
|
+
if (!path ||
|
|
64
|
+
path.startsWith("/") ||
|
|
65
|
+
path.includes("://") ||
|
|
66
|
+
path.split("?")[0].split("/").includes(".."))
|
|
67
|
+
throw new Error("Invalid relative Razorpay API path");
|
|
68
|
+
const started = Date.now(), context = { method, path, correlation: (0, node_crypto_1.randomUUID)() };
|
|
69
|
+
let status, payload, rawResponse;
|
|
70
|
+
const log = (level, message, data = {}) => this.logger[level](message, {
|
|
71
|
+
...context,
|
|
72
|
+
...data,
|
|
73
|
+
duration_ms: Math.max(0, Date.now() - started),
|
|
74
|
+
});
|
|
75
|
+
const requestFailure = (kind, existing) => {
|
|
76
|
+
const failure = existing ??
|
|
77
|
+
new GatewayRequestError(kind === "http"
|
|
78
|
+
? "Razorpay request failed; reconcile gateway state before retrying"
|
|
79
|
+
: kind === "response"
|
|
80
|
+
? "Razorpay response invalid; reconcile gateway state before retrying"
|
|
81
|
+
: "Razorpay request unavailable; reconcile gateway state before retrying", method, kind, status);
|
|
82
|
+
const severity = status === 401 || status === 403
|
|
83
|
+
? "critical"
|
|
84
|
+
: status !== undefined && status < 500 && kind === "http"
|
|
85
|
+
? "warning"
|
|
86
|
+
: "error";
|
|
87
|
+
const message = {
|
|
88
|
+
http: "Razorpay returned an unsuccessful HTTP response",
|
|
89
|
+
response: "Razorpay returned invalid JSON",
|
|
90
|
+
transport: "Razorpay transport failed",
|
|
91
|
+
};
|
|
92
|
+
log(severity, message[kind], {
|
|
93
|
+
http_status: status,
|
|
94
|
+
reconciliation_required: method !== "GET",
|
|
95
|
+
});
|
|
96
|
+
return failure;
|
|
97
|
+
};
|
|
98
|
+
let response;
|
|
99
|
+
log("debug", "Sending Razorpay API request", { request: body });
|
|
100
|
+
try {
|
|
101
|
+
const requestHeaders = new Headers(headers);
|
|
102
|
+
requestHeaders.set("Authorization", this.authorization);
|
|
103
|
+
requestHeaders.set("Content-Type", "application/json");
|
|
104
|
+
response = await this.transport("https://api.razorpay.com/v1/" + path, {
|
|
105
|
+
method,
|
|
106
|
+
headers: requestHeaders,
|
|
107
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
108
|
+
signal: AbortSignal.timeout(Math.ceil(Math.min(this.timeoutMs, Math.max(1, timeoutMs)))),
|
|
109
|
+
redirect: "error",
|
|
110
|
+
});
|
|
111
|
+
status = response.status;
|
|
112
|
+
rawResponse = await response.text();
|
|
113
|
+
payload = status === 204 ? undefined : JSON.parse(rawResponse);
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
const kind = status !== undefined && status >= 400
|
|
117
|
+
? "http"
|
|
118
|
+
: error instanceof SyntaxError
|
|
119
|
+
? "response"
|
|
120
|
+
: "transport";
|
|
121
|
+
throw requestFailure(kind, error instanceof GatewayRequestError ? error : undefined);
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
if (status !== undefined)
|
|
125
|
+
log("debug", "Received Razorpay API response", {
|
|
126
|
+
http_status: status,
|
|
127
|
+
response: payload === undefined ? rawResponse : payload,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
if (!response.ok)
|
|
131
|
+
throw requestFailure("http");
|
|
132
|
+
log(method === "GET" ? "debug" : "info", "Razorpay API request completed", {
|
|
133
|
+
http_status: status,
|
|
134
|
+
});
|
|
135
|
+
return payload;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
exports.RazorpayGateway = RazorpayGateway;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import RazorpayProvider from "./service";
|
|
2
|
+
export { RazorpayProvider };
|
|
3
|
+
export type { Options } from "./service";
|
|
4
|
+
declare const _default: import("@medusajs/types").ModuleProviderExports;
|
|
5
|
+
export default _default;
|
|
6
|
+
export { reconcileRazorpayPayment, gatewayReader } from "./reconciliation";
|
|
7
|
+
export type { ReconciliationOptions, RazorpayReconciliationReport, } from "./reconciliation";
|
|
8
|
+
export { signedRefundEvent, observeRazorpayRefund } from "./refund-observation";
|
|
9
|
+
export type { RefundObservationDependencies } from "./refund-observation";
|
|
10
|
+
export { verify as verifyRazorpayWebhook, verifyRazorpayCheckout, } from "./security";
|
|
11
|
+
export { importRazorpayRefund } from "./refund-import";
|
|
12
|
+
export type { RefundImportOptions } from "./refund-import";
|
|
13
|
+
export { reconcileRazorpayRefund, RAZORPAY_REFUND_RECOVERY_EVENT, REFUND_RECOVERY_DELAY_MS, } from "./refund-recovery";
|
|
14
|
+
export type { RefundRecoveryEvent } from "./refund-recovery";
|
|
15
|
+
export { PendingRefundRecoveryError } from "./refund-recovery-error";
|
|
16
|
+
export { GatewayRefundPendingError } from "./gateway-refund-pending-error";
|
|
17
|
+
export { GatewayRefundReconciliationError } from "./gateway-refund-reconciliation-error";
|
|
18
|
+
export { LOG_LEVELS, validateLogLevel } from "./logger";
|
|
19
|
+
export type { LogLevel } from "./logger";
|
|
20
|
+
export { RazorpayGateway, GatewayRequestError } from "./gateway";
|
|
21
|
+
export { createLogger } from "./logger";
|
|
22
|
+
export type { LoggerSink, PluginLogger, LoggerOptions, LogContext, } from "./logger";
|
|
23
|
+
export type { GatewayOptions, HttpMethod, GatewayFailureKind } from "./gateway";
|
|
24
|
+
export type { GatewayReader } from "./reconciliation";
|
|
25
|
+
export { RazorpayRefundRejectedError } from "./razorpay-refund-rejected-error";
|
|
26
|
+
export { validateRazorpayCredentials } from "./configuration";
|
|
27
|
+
export type { RazorpayMode, RazorpayCredentials } from "./configuration";
|
|
28
|
+
export { createRazorpayCoordinator } from "./financial-coordination";
|
|
29
|
+
export type { FinancialCoordinator, FinancialCoordinationDependencies, SessionOrderAssociation, } from "./financial-coordination";
|
|
30
|
+
export { assessRazorpayRefundRecovery, recoverRazorpayRefund, } from "./operator-recovery";
|
|
31
|
+
export type { RefundRecoveryTarget, RefundRecoveryAssessment, RefundRecoveryControl, } from "./operator-recovery";
|
|
32
|
+
export { OperatorRefundRecoveryRequiredError } from "./operator-recovery-required-error";
|
|
33
|
+
export { createRazorpayRecoveryOptions } from "./operator-configuration";
|
|
34
|
+
export type { RefundRecoveryConfiguration, RefundRecoveryConfigurationFactory, } from "./operator-configuration";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createRazorpayRecoveryOptions = exports.OperatorRefundRecoveryRequiredError = exports.recoverRazorpayRefund = exports.assessRazorpayRefundRecovery = exports.createRazorpayCoordinator = exports.validateRazorpayCredentials = exports.RazorpayRefundRejectedError = exports.createLogger = exports.GatewayRequestError = exports.RazorpayGateway = exports.validateLogLevel = exports.LOG_LEVELS = exports.GatewayRefundReconciliationError = exports.GatewayRefundPendingError = exports.PendingRefundRecoveryError = exports.REFUND_RECOVERY_DELAY_MS = exports.RAZORPAY_REFUND_RECOVERY_EVENT = exports.reconcileRazorpayRefund = exports.importRazorpayRefund = exports.verifyRazorpayCheckout = exports.verifyRazorpayWebhook = exports.observeRazorpayRefund = exports.signedRefundEvent = exports.gatewayReader = exports.reconcileRazorpayPayment = exports.RazorpayProvider = void 0;
|
|
7
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
8
|
+
const service_1 = __importDefault(require("./service"));
|
|
9
|
+
exports.RazorpayProvider = service_1.default;
|
|
10
|
+
exports.default = (0, utils_1.ModuleProvider)(utils_1.Modules.PAYMENT, { services: [service_1.default] });
|
|
11
|
+
var reconciliation_1 = require("./reconciliation");
|
|
12
|
+
Object.defineProperty(exports, "reconcileRazorpayPayment", { enumerable: true, get: function () { return reconciliation_1.reconcileRazorpayPayment; } });
|
|
13
|
+
Object.defineProperty(exports, "gatewayReader", { enumerable: true, get: function () { return reconciliation_1.gatewayReader; } });
|
|
14
|
+
var refund_observation_1 = require("./refund-observation");
|
|
15
|
+
Object.defineProperty(exports, "signedRefundEvent", { enumerable: true, get: function () { return refund_observation_1.signedRefundEvent; } });
|
|
16
|
+
Object.defineProperty(exports, "observeRazorpayRefund", { enumerable: true, get: function () { return refund_observation_1.observeRazorpayRefund; } });
|
|
17
|
+
var security_1 = require("./security");
|
|
18
|
+
Object.defineProperty(exports, "verifyRazorpayWebhook", { enumerable: true, get: function () { return security_1.verify; } });
|
|
19
|
+
Object.defineProperty(exports, "verifyRazorpayCheckout", { enumerable: true, get: function () { return security_1.verifyRazorpayCheckout; } });
|
|
20
|
+
var refund_import_1 = require("./refund-import");
|
|
21
|
+
Object.defineProperty(exports, "importRazorpayRefund", { enumerable: true, get: function () { return refund_import_1.importRazorpayRefund; } });
|
|
22
|
+
var refund_recovery_1 = require("./refund-recovery");
|
|
23
|
+
Object.defineProperty(exports, "reconcileRazorpayRefund", { enumerable: true, get: function () { return refund_recovery_1.reconcileRazorpayRefund; } });
|
|
24
|
+
Object.defineProperty(exports, "RAZORPAY_REFUND_RECOVERY_EVENT", { enumerable: true, get: function () { return refund_recovery_1.RAZORPAY_REFUND_RECOVERY_EVENT; } });
|
|
25
|
+
Object.defineProperty(exports, "REFUND_RECOVERY_DELAY_MS", { enumerable: true, get: function () { return refund_recovery_1.REFUND_RECOVERY_DELAY_MS; } });
|
|
26
|
+
var refund_recovery_error_1 = require("./refund-recovery-error");
|
|
27
|
+
Object.defineProperty(exports, "PendingRefundRecoveryError", { enumerable: true, get: function () { return refund_recovery_error_1.PendingRefundRecoveryError; } });
|
|
28
|
+
var gateway_refund_pending_error_1 = require("./gateway-refund-pending-error");
|
|
29
|
+
Object.defineProperty(exports, "GatewayRefundPendingError", { enumerable: true, get: function () { return gateway_refund_pending_error_1.GatewayRefundPendingError; } });
|
|
30
|
+
var gateway_refund_reconciliation_error_1 = require("./gateway-refund-reconciliation-error");
|
|
31
|
+
Object.defineProperty(exports, "GatewayRefundReconciliationError", { enumerable: true, get: function () { return gateway_refund_reconciliation_error_1.GatewayRefundReconciliationError; } });
|
|
32
|
+
var logger_1 = require("./logger");
|
|
33
|
+
Object.defineProperty(exports, "LOG_LEVELS", { enumerable: true, get: function () { return logger_1.LOG_LEVELS; } });
|
|
34
|
+
Object.defineProperty(exports, "validateLogLevel", { enumerable: true, get: function () { return logger_1.validateLogLevel; } });
|
|
35
|
+
var gateway_1 = require("./gateway");
|
|
36
|
+
Object.defineProperty(exports, "RazorpayGateway", { enumerable: true, get: function () { return gateway_1.RazorpayGateway; } });
|
|
37
|
+
Object.defineProperty(exports, "GatewayRequestError", { enumerable: true, get: function () { return gateway_1.GatewayRequestError; } });
|
|
38
|
+
var logger_2 = require("./logger");
|
|
39
|
+
Object.defineProperty(exports, "createLogger", { enumerable: true, get: function () { return logger_2.createLogger; } });
|
|
40
|
+
var razorpay_refund_rejected_error_1 = require("./razorpay-refund-rejected-error");
|
|
41
|
+
Object.defineProperty(exports, "RazorpayRefundRejectedError", { enumerable: true, get: function () { return razorpay_refund_rejected_error_1.RazorpayRefundRejectedError; } });
|
|
42
|
+
var configuration_1 = require("./configuration");
|
|
43
|
+
Object.defineProperty(exports, "validateRazorpayCredentials", { enumerable: true, get: function () { return configuration_1.validateRazorpayCredentials; } });
|
|
44
|
+
var financial_coordination_1 = require("./financial-coordination");
|
|
45
|
+
Object.defineProperty(exports, "createRazorpayCoordinator", { enumerable: true, get: function () { return financial_coordination_1.createRazorpayCoordinator; } });
|
|
46
|
+
var operator_recovery_1 = require("./operator-recovery");
|
|
47
|
+
Object.defineProperty(exports, "assessRazorpayRefundRecovery", { enumerable: true, get: function () { return operator_recovery_1.assessRazorpayRefundRecovery; } });
|
|
48
|
+
Object.defineProperty(exports, "recoverRazorpayRefund", { enumerable: true, get: function () { return operator_recovery_1.recoverRazorpayRefund; } });
|
|
49
|
+
var operator_recovery_required_error_1 = require("./operator-recovery-required-error");
|
|
50
|
+
Object.defineProperty(exports, "OperatorRefundRecoveryRequiredError", { enumerable: true, get: function () { return operator_recovery_required_error_1.OperatorRefundRecoveryRequiredError; } });
|
|
51
|
+
var operator_configuration_1 = require("./operator-configuration");
|
|
52
|
+
Object.defineProperty(exports, "createRazorpayRecoveryOptions", { enumerable: true, get: function () { return operator_configuration_1.createRazorpayRecoveryOptions; } });
|