@delopay/sdk 0.34.0 → 0.35.1
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/README.md +102 -0
- package/dist/index.d.cts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/internal.cjs +42 -0
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +59 -3
- package/dist/internal.d.ts +59 -3
- package/dist/internal.js +42 -0
- package/dist/internal.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -171,6 +171,108 @@ const gateway = await delopay.shops.gateways.connect(merchantId, shop.shop_id, {
|
|
|
171
171
|
const gateways = await delopay.shops.gateways.list(merchantId, shop.shop_id);
|
|
172
172
|
```
|
|
173
173
|
|
|
174
|
+
### Subscriptions
|
|
175
|
+
|
|
176
|
+
Recurring billing runs through a billing processor connected to the shop (Stripe
|
|
177
|
+
Billing or PayPal). Every subscription call is **profile-scoped** — pass the
|
|
178
|
+
shop's `X-Profile-Id` so the backend can resolve the billing processor (you get
|
|
179
|
+
`IR_04` otherwise):
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
const opts = { headers: { 'X-Profile-Id': profileId } };
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Browse plans and estimate cost** before creating anything:
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
// List purchasable plans (or addons) with their prices
|
|
189
|
+
const plans = await delopay.subscriptions.getItems({ item_type: 'plan' }, opts);
|
|
190
|
+
const priceId = plans[0]?.price_id[0]?.price_id;
|
|
191
|
+
|
|
192
|
+
// Preview what the customer will be charged
|
|
193
|
+
const estimate = await delopay.subscriptions.getEstimate({ item_price_id: priceId }, opts);
|
|
194
|
+
console.log(estimate.amount, estimate.currency, estimate.interval); // 1500 'EUR' 'Month'
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
> **Never send raw card numbers.** The subscription API rejects
|
|
198
|
+
> `payment_method_data.card` with a raw PAN. Cards are collected client-side by
|
|
199
|
+
> the connector's hosted fields (Stripe Elements) so the card never touches your
|
|
200
|
+
> server, keeping raw card data out of your PCI scope. Confirm with a hosted
|
|
201
|
+
> checkout session or a previously-saved token, as shown below.
|
|
202
|
+
|
|
203
|
+
**Recommended: hosted checkout.** Create the subscription server-side, then send
|
|
204
|
+
the buyer to the Delopay hosted checkout with the returned `client_secret`. The
|
|
205
|
+
buyer enters their card in the connector iframe; you never handle the PAN:
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
const pending = await delopay.subscriptions.create(
|
|
209
|
+
{
|
|
210
|
+
item_price_id: priceId,
|
|
211
|
+
customer_id: 'cus_abc123',
|
|
212
|
+
payment_details: { return_url: 'https://example.com/subscription/complete' },
|
|
213
|
+
},
|
|
214
|
+
opts,
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
// Redirect the buyer to the hosted checkout to enter their card.
|
|
218
|
+
const checkoutUrl =
|
|
219
|
+
`https://checkout.delopay.net/pay/${merchantId}/${pending.id}` +
|
|
220
|
+
`?cs=${encodeURIComponent(pending.client_secret ?? '')}`;
|
|
221
|
+
// → res.redirect(checkoutUrl)
|
|
222
|
+
|
|
223
|
+
// Activation arrives via the subscription/invoice webhooks; never trust the
|
|
224
|
+
// client. Reconcile with subscriptions.retrieve(pending.id, opts).
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Saved payment method (off-session).** If the customer already has a saved,
|
|
228
|
+
tokenized payment method, confirm server-side with the token — still no PAN:
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
const sub = await delopay.subscriptions.createAndConfirm(
|
|
232
|
+
{
|
|
233
|
+
item_price_id: priceId,
|
|
234
|
+
customer_id: 'cus_abc123',
|
|
235
|
+
payment_details: {
|
|
236
|
+
payment_method: 'card',
|
|
237
|
+
payment_method_id: savedPaymentMethodId, // token, not a card number
|
|
238
|
+
setup_future_usage: 'off_session',
|
|
239
|
+
return_url: 'https://example.com/subscription/complete',
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
opts,
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
if (sub.redirect_url) {
|
|
246
|
+
// Some processors (e.g. PayPal) still need buyer approval — redirect there.
|
|
247
|
+
} else {
|
|
248
|
+
console.log(sub.status); // 'active'
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
You can also split create and confirm — call `subscriptions.confirm(id, …)` with
|
|
253
|
+
the `client_secret` and a `payment_token` once the buyer has a token. Same rule:
|
|
254
|
+
a `payment_token` / `payment_method_id`, never a raw card.
|
|
255
|
+
|
|
256
|
+
**Manage the lifecycle.** Pause, resume, and cancel take optional timing and
|
|
257
|
+
proration controls; called with no body they act immediately:
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
await delopay.subscriptions.pause(sub.id, { pause_option: 'end_of_term' }, opts);
|
|
261
|
+
await delopay.subscriptions.resume(sub.id, undefined, opts);
|
|
262
|
+
await delopay.subscriptions.cancel(
|
|
263
|
+
sub.id,
|
|
264
|
+
{ cancel_option: 'immediately', credit_option_for_current_term_charges: 'prorate' },
|
|
265
|
+
opts,
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
// Retrieve one, or list for the profile
|
|
269
|
+
const current = await delopay.subscriptions.retrieve(sub.id, opts);
|
|
270
|
+
const all = await delopay.subscriptions.list({ limit: 20 }, opts);
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Each billing cycle raises an invoice (`sub.invoice`) with its own payment leg
|
|
274
|
+
(`sub.payment`); track cycle outcomes via the subscription/invoice webhooks.
|
|
275
|
+
|
|
174
276
|
### Webhook verification
|
|
175
277
|
|
|
176
278
|
Delopay signs each outgoing webhook with HMAC-SHA512 over the raw request body and delivers the hex-encoded digest in the `X-Webhook-Signature-512` header. Use `express.raw()` (not `express.json()`) so the bytes reach the verifier unchanged.
|
package/dist/index.d.cts
CHANGED
|
@@ -840,6 +840,19 @@ interface BillingProfileResponse {
|
|
|
840
840
|
consecutive_recharge_failures: number;
|
|
841
841
|
stripe_customer_id?: string | null;
|
|
842
842
|
suspended_at?: string | null;
|
|
843
|
+
/**
|
|
844
|
+
* Whether the merchant is on the trusted list. Trusted merchants are
|
|
845
|
+
* exempt from automatic AND manual suspension until the flag is cleared.
|
|
846
|
+
*/
|
|
847
|
+
is_trusted: boolean;
|
|
848
|
+
/**
|
|
849
|
+
* What caused the current suspension: `auto_recharge` or `admin`. Absent
|
|
850
|
+
* when the merchant is not suspended. An `admin` suspension is sticky — a
|
|
851
|
+
* top-up will not auto-reactivate it; only an admin unsuspend lifts it.
|
|
852
|
+
*/
|
|
853
|
+
suspension_source?: string | null;
|
|
854
|
+
/** Admin-provided reason for a manual suspension. Absent otherwise. */
|
|
855
|
+
suspension_reason?: string | null;
|
|
843
856
|
created_at: string;
|
|
844
857
|
modified_at: string;
|
|
845
858
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -840,6 +840,19 @@ interface BillingProfileResponse {
|
|
|
840
840
|
consecutive_recharge_failures: number;
|
|
841
841
|
stripe_customer_id?: string | null;
|
|
842
842
|
suspended_at?: string | null;
|
|
843
|
+
/**
|
|
844
|
+
* Whether the merchant is on the trusted list. Trusted merchants are
|
|
845
|
+
* exempt from automatic AND manual suspension until the flag is cleared.
|
|
846
|
+
*/
|
|
847
|
+
is_trusted: boolean;
|
|
848
|
+
/**
|
|
849
|
+
* What caused the current suspension: `auto_recharge` or `admin`. Absent
|
|
850
|
+
* when the merchant is not suspended. An `admin` suspension is sticky — a
|
|
851
|
+
* top-up will not auto-reactivate it; only an admin unsuspend lifts it.
|
|
852
|
+
*/
|
|
853
|
+
suspension_source?: string | null;
|
|
854
|
+
/** Admin-provided reason for a manual suspension. Absent otherwise. */
|
|
855
|
+
suspension_reason?: string | null;
|
|
843
856
|
created_at: string;
|
|
844
857
|
modified_at: string;
|
|
845
858
|
/**
|
package/dist/internal.cjs
CHANGED
|
@@ -4010,6 +4010,48 @@ var PlatformBilling = class {
|
|
|
4010
4010
|
body: params
|
|
4011
4011
|
});
|
|
4012
4012
|
}
|
|
4013
|
+
/**
|
|
4014
|
+
* Manually suspend a merchant (e.g. confirmed fraud or ToS violation),
|
|
4015
|
+
* independent of balance. A `reason` is required for audit. Throws 412 if
|
|
4016
|
+
* the merchant is trusted (clear the flag first) or already suspended.
|
|
4017
|
+
*
|
|
4018
|
+
* @param merchantId - The merchant account ID.
|
|
4019
|
+
* @param params - Suspension reason.
|
|
4020
|
+
* @returns The updated billing profile.
|
|
4021
|
+
*/
|
|
4022
|
+
async suspend(merchantId, params) {
|
|
4023
|
+
return this.request("POST", `/billing/${encodeURIComponent(merchantId)}/admin/suspend`, {
|
|
4024
|
+
body: params
|
|
4025
|
+
});
|
|
4026
|
+
}
|
|
4027
|
+
/**
|
|
4028
|
+
* Lift a suspension. Restores the merchant to `active` (or `delinquent` if
|
|
4029
|
+
* the balance is at/below the hard floor) and resets the recharge-failure
|
|
4030
|
+
* counter. Throws 412 if the merchant is not suspended.
|
|
4031
|
+
*
|
|
4032
|
+
* @param merchantId - The merchant account ID.
|
|
4033
|
+
* @param params - Optional audit note.
|
|
4034
|
+
* @returns The updated billing profile.
|
|
4035
|
+
*/
|
|
4036
|
+
async unsuspend(merchantId, params = {}) {
|
|
4037
|
+
return this.request("POST", `/billing/${encodeURIComponent(merchantId)}/admin/unsuspend`, {
|
|
4038
|
+
body: params
|
|
4039
|
+
});
|
|
4040
|
+
}
|
|
4041
|
+
/**
|
|
4042
|
+
* Set or clear the trusted (suspension-exempt) flag. Trusted merchants
|
|
4043
|
+
* cannot be suspended automatically or manually. Does not lift an existing
|
|
4044
|
+
* suspension — use {@link PlatformBilling.unsuspend} for that.
|
|
4045
|
+
*
|
|
4046
|
+
* @param merchantId - The merchant account ID.
|
|
4047
|
+
* @param params - The desired trusted state.
|
|
4048
|
+
* @returns The updated billing profile.
|
|
4049
|
+
*/
|
|
4050
|
+
async setTrusted(merchantId, params) {
|
|
4051
|
+
return this.request("PATCH", `/billing/${encodeURIComponent(merchantId)}/admin/trusted`, {
|
|
4052
|
+
body: params
|
|
4053
|
+
});
|
|
4054
|
+
}
|
|
4013
4055
|
};
|
|
4014
4056
|
|
|
4015
4057
|
// src/internal/resources/platformFees.ts
|