@paykit-sdk/gopay 1.1.3 → 1.2.0

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/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { schema, validateRequiredKeys, AbstractPayKitProvider, HTTPClient, OAuth2TokenManager, createCheckoutSchema, ValidationError, isEmailCustomer, InvalidTypeError, PAYKIT_METADATA_KEY, OperationFailedError, ProviderNotSupportedError, createSubscriptionSchema, ConfigurationError, createPaymentSchema, createRefundSchema, WebhookError, tryCatchAsync, paykitEvent$InboundSchema, omitInternalMetadata } from '@paykit-sdk/core';
1
+ import { schema, validateRequiredKeys, AbstractPayKitProvider, HTTPClient, OAuth2TokenManager, createCheckoutSchema, ValidationError, isEmailCustomer, InvalidTypeError, PAYKIT_METADATA_KEY, OperationFailedError, ProviderNotSupportedError, createSubscriptionSchema, isIdCustomer, createPaymentSchema, ConfigurationError, createRefundSchema, WebhookError, tryCatchAsync, paykitEvent$InboundSchema, omitInternalMetadata } from '@paykit-sdk/core';
2
2
  import * as crypto from 'crypto';
3
3
 
4
4
  var __defProp = Object.defineProperty;
@@ -4049,10 +4049,12 @@ var NEVER = INVALID;
4049
4049
  var decodeHtmlEntities = (str) => {
4050
4050
  return str.replace(/"/g, '"').replace(/'/g, "'").replace(/"/g, '"').replace(/'/g, "'");
4051
4051
  };
4052
- var paykitPayment$InboundSchema = (data) => {
4052
+ var Payment$inboundSchema = (data) => {
4053
4053
  const { item } = JSON.parse(
4054
4054
  decodeHtmlEntities(
4055
- data.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4055
+ data.additional_params?.find(
4056
+ (param) => param.name === PAYKIT_METADATA_KEY
4057
+ )?.value ?? "{}"
4056
4058
  )
4057
4059
  );
4058
4060
  const metadata = omitInternalMetadata(
@@ -4079,7 +4081,7 @@ var paykitPayment$InboundSchema = (data) => {
4079
4081
  id: data.id.toString(),
4080
4082
  amount: data.amount,
4081
4083
  currency: data.currency,
4082
- customer: data.payer?.contact?.email ? { email: data.payer.contact.email } : "",
4084
+ customer: data.payer?.contact?.email ? { email: data.payer.contact.email } : null,
4083
4085
  status: statusMap[data.state],
4084
4086
  item_id: item,
4085
4087
  metadata,
@@ -4087,10 +4089,12 @@ var paykitPayment$InboundSchema = (data) => {
4087
4089
  payment_url: data.gw_url ?? null
4088
4090
  };
4089
4091
  };
4090
- var paykitCheckout$InboundSchema = (data) => {
4092
+ var Checkout$inboundSchema = (data) => {
4091
4093
  const { item, qty, type } = JSON.parse(
4092
4094
  decodeHtmlEntities(
4093
- data.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4095
+ data.additional_params?.find(
4096
+ (param) => param.name === PAYKIT_METADATA_KEY
4097
+ )?.value ?? "{}"
4094
4098
  )
4095
4099
  );
4096
4100
  const metadata = omitInternalMetadata(
@@ -4106,24 +4110,28 @@ var paykitCheckout$InboundSchema = (data) => {
4106
4110
  id: data.id.toString(),
4107
4111
  amount: data.amount,
4108
4112
  currency: data.currency,
4109
- customer: data.payer?.contact?.email ? { email: data.payer.contact.email } : "",
4113
+ customer: data.payer?.contact?.email ? { email: data.payer.contact.email } : null,
4110
4114
  payment_url: data.gw_url ?? "",
4111
4115
  metadata,
4112
4116
  session_type: type,
4113
4117
  products: [{ id: item, quantity: parseInt(qty) }]
4114
4118
  };
4115
4119
  };
4116
- var paykitInvoice$InboundSchema = (data, isSubscription) => {
4120
+ var Invoice$inboundSchema = (data, isSubscription) => {
4117
4121
  const { item, qty } = JSON.parse(
4118
4122
  decodeHtmlEntities(
4119
- data.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4123
+ data.additional_params?.find(
4124
+ (param) => param.name === PAYKIT_METADATA_KEY
4125
+ )?.value ?? "{}"
4120
4126
  )
4121
4127
  );
4122
4128
  const status = (() => {
4123
4129
  if (data.state === "PAID") return "paid";
4124
4130
  return "open";
4125
4131
  })();
4126
- const paidAt = isSubscription ? new Date(data.recurrence?.recurrence_date_to ?? "") : /* @__PURE__ */ new Date();
4132
+ const paidAt = isSubscription ? new Date(
4133
+ data.recurrence?.recurrence_date_to ?? ""
4134
+ ) : /* @__PURE__ */ new Date();
4127
4135
  const metadata = omitInternalMetadata(
4128
4136
  data.additional_params?.reduce(
4129
4137
  (acc, param) => {
@@ -4137,7 +4145,7 @@ var paykitInvoice$InboundSchema = (data, isSubscription) => {
4137
4145
  id: data.id.toString(),
4138
4146
  amount_paid: data.amount,
4139
4147
  currency: data.currency,
4140
- customer: data.payer?.contact?.email ? { email: data.payer.contact.email } : "",
4148
+ customer: data.payer?.contact?.email ? { email: data.payer.contact.email } : null,
4141
4149
  status,
4142
4150
  paid_at: paidAt.toISOString(),
4143
4151
  metadata: metadata ?? {},
@@ -4147,10 +4155,12 @@ var paykitInvoice$InboundSchema = (data, isSubscription) => {
4147
4155
  line_items: [{ id: item, quantity: parseInt(qty) }]
4148
4156
  };
4149
4157
  };
4150
- var paykitSubscription$InboundSchema = (data) => {
4158
+ var Subscription$inboundSchema = (data) => {
4151
4159
  const { item } = JSON.parse(
4152
4160
  decodeHtmlEntities(
4153
- data.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4161
+ data.additional_params?.find(
4162
+ (param) => param.name === PAYKIT_METADATA_KEY
4163
+ )?.value ?? "{}"
4154
4164
  )
4155
4165
  );
4156
4166
  const billingIntervalMap = {
@@ -4162,7 +4172,9 @@ var paykitSubscription$InboundSchema = (data) => {
4162
4172
  const billingInterval = billingIntervalMap[data.recurrence?.recurrence_cycle ?? "ON_DEMAND"];
4163
4173
  const recurrencePeriod = data.recurrence?.recurrence_period ?? 1;
4164
4174
  const recurrenceCycle = data.recurrence?.recurrence_cycle;
4165
- const currentPeriodEnd = new Date(data.recurrence?.recurrence_date_to ?? "");
4175
+ const currentPeriodEnd = new Date(
4176
+ data.recurrence?.recurrence_date_to ?? ""
4177
+ );
4166
4178
  const currentPeriodStart = (() => {
4167
4179
  if (!currentPeriodEnd) return /* @__PURE__ */ new Date();
4168
4180
  const endDate = new Date(currentPeriodEnd);
@@ -4192,21 +4204,21 @@ var paykitSubscription$InboundSchema = (data) => {
4192
4204
  ) ?? {}
4193
4205
  );
4194
4206
  const requiresAction = data.state === "CREATED" ? true : false;
4195
- const status = (() => {
4196
- if (data.state === "CREATED") return "pending";
4197
- if (data.state === "PAID") return "active";
4198
- if (data.state === "CANCELED") return "canceled";
4199
- if (data.state === "TIMEOUTED") return "canceled";
4200
- if (data.state === "REFUNDED") return "canceled";
4201
- if (data.state === "PARTIALLY_REFUNDED") return "canceled";
4202
- if (data.state === "AUTHORIZED") return "active";
4203
- if (data.state === "PAYMENT_METHOD_CHOSEN") return "active";
4204
- return "pending";
4205
- })();
4207
+ const subscriptionStatusMap = {
4208
+ CREATED: "pending",
4209
+ PAID: "active",
4210
+ CANCELED: "canceled",
4211
+ TIMEOUTED: "canceled",
4212
+ REFUNDED: "canceled",
4213
+ PARTIALLY_REFUNDED: "canceled",
4214
+ AUTHORIZED: "active",
4215
+ PAYMENT_METHOD_CHOSEN: "active"
4216
+ };
4217
+ const status = subscriptionStatusMap[data.state] ?? "expired";
4206
4218
  return {
4207
4219
  id: data.id.toString(),
4208
4220
  status,
4209
- customer: data.payer?.contact?.email ? { email: data.payer.contact.email } : "",
4221
+ customer: data.payer?.contact?.email ? { email: data.payer.contact.email } : null,
4210
4222
  item_id: item,
4211
4223
  billing_interval: billingInterval,
4212
4224
  currency: data.currency,
@@ -4219,7 +4231,7 @@ var paykitSubscription$InboundSchema = (data) => {
4219
4231
  payment_url: requiresAction ? data.gw_url ?? null : null
4220
4232
  };
4221
4233
  };
4222
- var paykitRefund$InboundSchema = (data) => {
4234
+ var Refund$inboundSchema = (data) => {
4223
4235
  return {
4224
4236
  id: data.id.toString(),
4225
4237
  amount: data.amount,
@@ -4245,6 +4257,7 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4245
4257
  constructor(opts) {
4246
4258
  super(gopayOptionsSchema, opts, providerName);
4247
4259
  this.opts = opts;
4260
+ this.isSandbox = opts.isSandbox;
4248
4261
  const debug = opts.debug ?? true;
4249
4262
  this.baseUrl = opts.isSandbox ? "https://gw.sandbox.gopay.com/api" : "https://gate.gopay.cz/api";
4250
4263
  this._client = new HTTPClient({
@@ -4256,7 +4269,10 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4256
4269
  client: this._client,
4257
4270
  provider: this.providerName,
4258
4271
  tokenEndpoint: "/oauth2/token",
4259
- credentials: { username: opts.clientId, password: opts.clientSecret },
4272
+ credentials: {
4273
+ username: opts.clientId,
4274
+ password: opts.clientSecret
4275
+ },
4260
4276
  responseAdapter: (response) => ({
4261
4277
  accessToken: response.access_token,
4262
4278
  expiresIn: response.expires_in
@@ -4275,17 +4291,33 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4275
4291
  });
4276
4292
  }
4277
4293
  providerName = providerName;
4294
+ providerVersion = "1.2.0";
4278
4295
  _client;
4279
4296
  baseUrl;
4297
+ isSandbox;
4280
4298
  tokenManager;
4299
+ get _native() {
4300
+ return null;
4301
+ }
4281
4302
  createCheckout = async (params) => {
4282
4303
  const { error, data } = createCheckoutSchema.safeParse(params);
4283
- if (error) throw ValidationError.fromZodError(error, "gopay", "createCheckout");
4304
+ if (error) {
4305
+ throw ValidationError.fromZodError(
4306
+ error,
4307
+ "gopay",
4308
+ "createCheckout"
4309
+ );
4310
+ }
4284
4311
  if (!isEmailCustomer(data.customer)) {
4285
- throw new InvalidTypeError("customer", "object (customer) with email", "string", {
4286
- provider: this.providerName,
4287
- method: "createCheckout"
4288
- });
4312
+ throw new InvalidTypeError(
4313
+ "customer",
4314
+ "object (customer) with email",
4315
+ "string",
4316
+ {
4317
+ provider: this.providerName,
4318
+ method: "createCheckout"
4319
+ }
4320
+ );
4289
4321
  }
4290
4322
  const { amount, currency = "CZK" } = validateRequiredKeys(
4291
4323
  ["amount", "currency"],
@@ -4312,9 +4344,9 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4312
4344
  },
4313
4345
  target: { type: "ACCOUNT", goid: parseInt(this.opts.goId) },
4314
4346
  amount: Number(amount),
4315
- currency,
4347
+ currency: currency.toUpperCase(),
4316
4348
  order_number: crypto.randomBytes(8).toString("hex").slice(0, 15),
4317
- order_description: data.metadata?.description || "Checkout",
4349
+ order_description: `Payment for ${data.item_id} by ${data.customer.email}`,
4318
4350
  items: [
4319
4351
  {
4320
4352
  name: data.item_id,
@@ -4324,7 +4356,10 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4324
4356
  }
4325
4357
  ],
4326
4358
  lang: data.provider_metadata?.language ? data.provider_metadata.language : "EN",
4327
- callback: { return_url: data.success_url, notification_url: this.opts.webhookUrl },
4359
+ callback: {
4360
+ return_url: data.success_url,
4361
+ notification_url: this.opts.webhookUrl
4362
+ },
4328
4363
  additional_params: Object.entries({
4329
4364
  ...data.metadata,
4330
4365
  [PAYKIT_METADATA_KEY]: JSON.stringify({
@@ -4345,11 +4380,15 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4345
4380
  }
4346
4381
  );
4347
4382
  if (!response.ok) {
4348
- throw new OperationFailedError("createCheckout", this.providerName, {
4349
- cause: new Error("Failed to create checkout")
4350
- });
4383
+ throw new OperationFailedError(
4384
+ "createCheckout",
4385
+ this.providerName,
4386
+ {
4387
+ cause: new Error("Failed to create checkout")
4388
+ }
4389
+ );
4351
4390
  }
4352
- return paykitCheckout$InboundSchema(response.value);
4391
+ return Checkout$inboundSchema(response.value);
4353
4392
  };
4354
4393
  retrieveCheckout = async (id) => {
4355
4394
  const response = await this._client.get(
@@ -4362,11 +4401,15 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4362
4401
  }
4363
4402
  );
4364
4403
  if (!response.ok) {
4365
- throw new OperationFailedError("retrieveCheckout", this.providerName, {
4366
- cause: new Error("Failed to retrieve checkout")
4367
- });
4404
+ throw new OperationFailedError(
4405
+ "retrieveCheckout",
4406
+ this.providerName,
4407
+ {
4408
+ cause: new Error("Failed to retrieve checkout")
4409
+ }
4410
+ );
4368
4411
  }
4369
- return paykitCheckout$InboundSchema(response.value);
4412
+ return Checkout$inboundSchema(response.value);
4370
4413
  };
4371
4414
  updateCheckout = async (id, params) => {
4372
4415
  if (this.opts.debug) {
@@ -4405,57 +4448,95 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4405
4448
  };
4406
4449
  createSubscription = async (params) => {
4407
4450
  const { error, data } = createSubscriptionSchema.safeParse(params);
4408
- if (error) throw ValidationError.fromZodError(error, "gopay", "createSubscription");
4409
- if (typeof data.customer == "string" || typeof data.customer === "object" && !data.customer.email) {
4410
- throw new InvalidTypeError("customer", "object (customer) with email", "string", {
4411
- provider: this.providerName,
4412
- method: "createCheckout"
4413
- });
4451
+ if (error)
4452
+ throw ValidationError.fromZodError(
4453
+ error,
4454
+ "gopay",
4455
+ "createSubscription"
4456
+ );
4457
+ if (!isEmailCustomer(data.customer)) {
4458
+ throw new InvalidTypeError(
4459
+ "customer",
4460
+ "object with email",
4461
+ isIdCustomer(data.customer) ? "object with id" : typeof data.customer,
4462
+ {
4463
+ provider: this.providerName,
4464
+ method: "createSubscription"
4465
+ }
4466
+ );
4414
4467
  }
4415
4468
  const { success_url } = validateRequiredKeys(
4416
4469
  ["success_url"],
4417
4470
  data.provider_metadata,
4418
- "The following fields must be present in the provider_metadata of createCheckout: {keys}"
4471
+ "The following fields must be present in the provider_metadata of createSubscription: {keys}"
4419
4472
  );
4473
+ const billingInterval = data.billing_interval;
4474
+ const isCustom = typeof billingInterval === "object" && billingInterval.type === "custom";
4475
+ const isYear = billingInterval === "year";
4476
+ const isOnDemand = isCustom || isYear;
4477
+ const intervalMap = {
4478
+ day: "DAY",
4479
+ week: "WEEK",
4480
+ month: "MONTH",
4481
+ year: "ON_DEMAND"
4482
+ };
4483
+ const recurrenceCycle = isCustom ? "ON_DEMAND" : intervalMap[billingInterval];
4420
4484
  if (this.opts.debug) {
4421
- if (data.billing_interval === "year") {
4485
+ if (isYear) {
4486
+ console.info(
4487
+ "[PayKit/GoPay] GoPay does not support yearly recurrence. Falling back to ON_DEMAND \u2014 you must trigger each charge manually via createRecurrence(parentPaymentId, ...). See: https://doc.gopay.com/#recurring-on-demand"
4488
+ );
4489
+ }
4490
+ if (isCustom) {
4491
+ const durationMs = billingInterval.durationMs;
4492
+ console.info(
4493
+ `[PayKit/GoPay] Custom interval (${durationMs}ms) is not supported by GoPay. Falling back to ON_DEMAND \u2014 trigger charges manually via createRecurrence(parentPaymentId, ...). See: https://doc.gopay.com/#recurring-on-demand`
4494
+ );
4495
+ }
4496
+ if (!isOnDemand) {
4497
+ console.info(
4498
+ `[PayKit/GoPay] AUTO recurrence (${recurrenceCycle}) \u2014 GoPay charges automatically each cycle. No createRecurrence() call is needed. Set provider_metadata.end_date (ISO string, e.g. "2027-01-01") to control when the subscription ends. Defaults to 1 year from today.`
4499
+ );
4500
+ } else {
4422
4501
  console.info(
4423
- "GoPay does not support yearly subscriptions, the available options are `day`, `week`, `month` and `ON_DEMAND` \n raise an issue at https://github.com/usepaykit/paykit-sdk/issues if you need this feature"
4502
+ "[PayKit/GoPay] ON_DEMAND recurrence \u2014 you MUST call createRecurrence(parentPaymentId, ...) for each subsequent charge. GoPay will NOT charge automatically. Set provider_metadata.end_date (ISO string) to control the authorization window. Defaults to 1 year (custom interval) or 5 years (yearly interval)."
4424
4503
  );
4425
4504
  }
4426
4505
  if (!data.provider_metadata?.description) {
4427
4506
  console.info(
4428
- `No description provided for the subscription \`provider_metadata.description\`, using default description \`Subscription by ${data.customer.email}\``
4507
+ `[PayKit/GoPay] No \`provider_metadata.description\` provided. Using default: "Subscription by ${data.customer.email}"`
4429
4508
  );
4430
4509
  }
4431
4510
  }
4432
- const intervalMap = {
4433
- day: "DAY",
4434
- week: "WEEK",
4435
- month: "MONTH",
4436
- year: "ON_DEMAND"
4511
+ const toDateString = (ms) => {
4512
+ const d = new Date(ms);
4513
+ return d.toISOString().split("T")[0];
4437
4514
  };
4438
- const recurrenceCycle = intervalMap?.[data.billing_interval] ?? "ON_DEMAND";
4439
- const currentPeriodEnd = (() => {
4440
- if (recurrenceCycle === "DAY") {
4441
- return new Date(Date.now() + 1 * 24 * 60 * 60 * 1e3).toISOString();
4442
- }
4443
- if (recurrenceCycle === "WEEK") {
4444
- return new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3).toISOString();
4445
- }
4446
- if (recurrenceCycle === "MONTH") {
4447
- return new Date(Date.now() + 30 * 24 * 60 * 60 * 1e3).toISOString();
4515
+ const GOPAY_MAX_DATE = "2099-12-30";
4516
+ const endDateOverride = data.provider_metadata?.end_date;
4517
+ const recurrenceDateTo = (() => {
4518
+ if (endDateOverride) {
4519
+ return endDateOverride < GOPAY_MAX_DATE ? endDateOverride : GOPAY_MAX_DATE;
4448
4520
  }
4449
4521
  if (recurrenceCycle === "ON_DEMAND") {
4450
- throw new ConfigurationError(
4451
- "ON_DEMAND subscriptions is not yet implemented by PayKit, please open an issue at https://github.com/usepaykit/paykit-sdk/issues",
4452
- {
4453
- provider: this.providerName
4454
- }
4522
+ if (isCustom) {
4523
+ return toDateString(Date.now() + 365 * 24 * 60 * 60 * 1e3);
4524
+ }
4525
+ return toDateString(
4526
+ Date.now() + 5 * 365 * 24 * 60 * 60 * 1e3
4455
4527
  );
4456
4528
  }
4457
- throw new Error("Invalid billing interval: " + data.billing_interval);
4529
+ return toDateString(Date.now() + 365 * 24 * 60 * 60 * 1e3);
4458
4530
  })();
4531
+ const recurrencePeriod = data.provider_metadata?.recurrence_period ?? 1;
4532
+ const recurrence = isOnDemand ? {
4533
+ recurrence_cycle: recurrenceCycle,
4534
+ recurrence_date_to: recurrenceDateTo
4535
+ } : {
4536
+ recurrence_cycle: recurrenceCycle,
4537
+ recurrence_period: recurrencePeriod,
4538
+ recurrence_date_to: recurrenceDateTo
4539
+ };
4459
4540
  const goPaySubscriptionOptions = {
4460
4541
  payer: {
4461
4542
  allowed_payment_instruments: ["PAYMENT_CARD"],
@@ -4466,24 +4547,28 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4466
4547
  amount: Number(data.amount),
4467
4548
  currency: data.currency ?? "CZK",
4468
4549
  order_number: crypto.randomBytes(8).toString("hex").slice(0, 15),
4469
- order_description: data.provider_metadata?.description ? data.provider_metadata.description : "Subscription by " + data.customer.email,
4470
- items: [{ name: data.item_id, amount: Number(data.amount), count: data.quantity }],
4471
- recurrence: {
4472
- recurrence_cycle: recurrenceCycle,
4473
- recurrence_period: data.quantity,
4474
- recurrence_date_to: currentPeriodEnd
4550
+ order_description: data.provider_metadata?.description ? data.provider_metadata.description : `Subscription by ${data.customer.email}`,
4551
+ items: [
4552
+ {
4553
+ name: data.item_id,
4554
+ amount: Number(data.amount),
4555
+ count: data.quantity ?? 1
4556
+ }
4557
+ ],
4558
+ recurrence,
4559
+ callback: {
4560
+ return_url: success_url,
4561
+ notification_url: this.opts.webhookUrl
4475
4562
  },
4476
- callback: { return_url: success_url, notification_url: this.opts.webhookUrl },
4477
4563
  additional_params: Object.entries({
4478
4564
  ...data.metadata,
4479
4565
  [PAYKIT_METADATA_KEY]: JSON.stringify({
4480
4566
  item: data.item_id,
4481
- qty: data.quantity
4567
+ qty: data.quantity,
4568
+ // Store the original interval so createRecurrence callers know the intended cadence
4569
+ billing_interval: isCustom ? `custom:${billingInterval.durationMs}ms` : billingInterval
4482
4570
  })
4483
- }).map(([name, value]) => ({
4484
- name,
4485
- value: String(value)
4486
- }))
4571
+ }).map(([name, value]) => ({ name, value: String(value) }))
4487
4572
  };
4488
4573
  const response = await this._client.post(
4489
4574
  "/payments/payment",
@@ -4493,28 +4578,42 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4493
4578
  }
4494
4579
  );
4495
4580
  if (!response.ok) {
4496
- throw new OperationFailedError("createSubscription", this.providerName, {
4497
- cause: new Error("Failed to create subscription")
4498
- });
4581
+ throw new OperationFailedError(
4582
+ "createSubscription",
4583
+ this.providerName,
4584
+ {
4585
+ cause: new Error(
4586
+ `[PayKit/GoPay] Failed to create subscription. Error: ${response.error}`
4587
+ )
4588
+ }
4589
+ );
4499
4590
  }
4500
- return paykitSubscription$InboundSchema(response.value);
4591
+ return Subscription$inboundSchema(response.value);
4501
4592
  };
4502
4593
  updateSubscription = async (id, params) => {
4503
4594
  const subscription = await this.retrieveSubscription(id);
4504
4595
  if (!subscription) {
4505
- throw new ProviderNotSupportedError("updateSubscription", this.providerName, {
4506
- reason: "Gopay doesn't support updating subscriptions",
4507
- alternative: "Use the payment API instead and update the subscription manually"
4508
- });
4596
+ throw new ProviderNotSupportedError(
4597
+ "updateSubscription",
4598
+ this.providerName,
4599
+ {
4600
+ reason: "Gopay doesn't support updating subscriptions",
4601
+ alternative: "Use the payment API instead and update the subscription manually"
4602
+ }
4603
+ );
4509
4604
  }
4510
4605
  return subscription;
4511
4606
  };
4512
4607
  cancelSubscription = async (id) => {
4513
4608
  const existingSubscription = await this.retrieveSubscription(id);
4514
4609
  if (!existingSubscription) {
4515
- throw new OperationFailedError("cancelSubscription", this.providerName, {
4516
- cause: new Error("Failed to retrieve subscription")
4517
- });
4610
+ throw new OperationFailedError(
4611
+ "cancelSubscription",
4612
+ this.providerName,
4613
+ {
4614
+ cause: new Error("Failed to retrieve subscription")
4615
+ }
4616
+ );
4518
4617
  }
4519
4618
  const response = await this._client.post(`/payments/payment/${id}/void-recurrence`, {
4520
4619
  headers: {
@@ -4524,7 +4623,9 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4524
4623
  });
4525
4624
  return {
4526
4625
  ...existingSubscription,
4527
- ...response.value?.result == "FINISHED" && { status: "canceled" }
4626
+ ...response.value?.result == "FINISHED" && {
4627
+ status: "canceled"
4628
+ }
4528
4629
  };
4529
4630
  };
4530
4631
  deleteSubscription = async (id) => {
@@ -4539,21 +4640,35 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4539
4640
  }
4540
4641
  );
4541
4642
  if (!response.ok) {
4542
- throw new OperationFailedError("retrieveSubscription", this.providerName, {
4543
- cause: new Error("Failed to retrieve subscription")
4544
- });
4643
+ throw new OperationFailedError(
4644
+ "retrieveSubscription",
4645
+ this.providerName,
4646
+ {
4647
+ cause: new Error("Failed to retrieve subscription")
4648
+ }
4649
+ );
4545
4650
  }
4546
- return paykitSubscription$InboundSchema(response.value);
4651
+ return Subscription$inboundSchema(response.value);
4547
4652
  };
4548
4653
  createPayment = async (params) => {
4549
4654
  const { error, data } = createPaymentSchema.safeParse(params);
4550
- if (error)
4551
- throw ValidationError.fromZodError(error, this.providerName, "createPayment");
4552
- if (typeof data.customer == "string" || typeof data.customer === "object" && !data.customer?.email) {
4553
- throw new InvalidTypeError("customer", "object (customer) with email", "string", {
4554
- provider: this.providerName,
4555
- method: "createPayment"
4556
- });
4655
+ if (error) {
4656
+ throw ValidationError.fromZodError(
4657
+ error,
4658
+ this.providerName,
4659
+ "createPayment"
4660
+ );
4661
+ }
4662
+ if (!isEmailCustomer(data.customer)) {
4663
+ throw new InvalidTypeError(
4664
+ "customer",
4665
+ "object with email",
4666
+ isIdCustomer(data.customer) ? "object with id" : typeof data.customer,
4667
+ {
4668
+ provider: this.providerName,
4669
+ method: "createPayment"
4670
+ }
4671
+ );
4557
4672
  }
4558
4673
  if (!data.item_id) {
4559
4674
  throw new ConfigurationError(
@@ -4578,20 +4693,40 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4578
4693
  payer: {
4579
4694
  allowed_payment_instruments: ["PAYMENT_CARD", "BANK_ACCOUNT"],
4580
4695
  default_payment_instrument: "PAYMENT_CARD",
4581
- contact: { email: data.customer.email }
4696
+ contact: { email: data.customer.email },
4697
+ ...data.billing && {
4698
+ city: data.billing.address.city,
4699
+ postal_code: data.billing.address.postal_code,
4700
+ country_code: data.billing.address.country,
4701
+ phone_number: data.billing.address.phone
4702
+ }
4582
4703
  },
4583
- callback: { return_url: successUrl, notification_url: this.opts.webhookUrl },
4584
4704
  target: { type: "ACCOUNT", goid: parseInt(this.opts.goId) },
4585
- amount: data.amount,
4705
+ amount: Number(data.amount),
4586
4706
  currency: data.currency ?? "CZK",
4587
4707
  order_number: crypto.randomBytes(8).toString("hex").slice(0, 15),
4588
4708
  order_description: `Payment for ${data.item_id} by ${data.customer.email}`,
4589
- items: [{ name: data.item_id, amount: data.amount, count: 1 }],
4709
+ items: [
4710
+ {
4711
+ name: data.item_id,
4712
+ amount: data.amount,
4713
+ count: 1,
4714
+ type: "ITEM"
4715
+ }
4716
+ ],
4717
+ lang: data.provider_metadata?.language ? data.provider_metadata.language : "EN",
4718
+ callback: {
4719
+ return_url: successUrl,
4720
+ notification_url: this.opts.webhookUrl
4721
+ },
4590
4722
  preauthorization: false,
4591
4723
  // automatically captures the payment
4592
4724
  additional_params: Object.entries({
4593
4725
  ...data.metadata,
4594
- [PAYKIT_METADATA_KEY]: JSON.stringify({ itemId: data.item_id, qty: 1 })
4726
+ [PAYKIT_METADATA_KEY]: JSON.stringify({
4727
+ itemId: data.item_id,
4728
+ qty: 1
4729
+ })
4595
4730
  }).map(([name, value]) => ({
4596
4731
  name,
4597
4732
  value: String(value)
@@ -4605,11 +4740,17 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4605
4740
  }
4606
4741
  );
4607
4742
  if (!response.ok) {
4608
- throw new OperationFailedError("createPayment", this.providerName, {
4609
- cause: new Error("Failed to create payment")
4610
- });
4743
+ throw new OperationFailedError(
4744
+ "createPayment",
4745
+ this.providerName,
4746
+ {
4747
+ cause: new Error(
4748
+ `Failed to create payment: ${JSON.stringify(response.error ?? response)}`
4749
+ )
4750
+ }
4751
+ );
4611
4752
  }
4612
- return paykitPayment$InboundSchema(response.value);
4753
+ return Payment$inboundSchema(response.value);
4613
4754
  };
4614
4755
  retrievePayment = async (id) => {
4615
4756
  const response = await this._client.get(
@@ -4622,17 +4763,25 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4622
4763
  }
4623
4764
  );
4624
4765
  if (!response.ok) {
4625
- throw new OperationFailedError("retrievePayment", this.providerName, {
4626
- cause: new Error("Failed to retrieve payment")
4627
- });
4766
+ throw new OperationFailedError(
4767
+ "retrievePayment",
4768
+ this.providerName,
4769
+ {
4770
+ cause: new Error("Failed to retrieve payment")
4771
+ }
4772
+ );
4628
4773
  }
4629
- return paykitPayment$InboundSchema(response.value);
4774
+ return Payment$inboundSchema(response.value);
4630
4775
  };
4631
4776
  deletePayment = async (id) => {
4632
- throw new ProviderNotSupportedError("deletePayment", this.providerName, {
4633
- reason: "GoPay does not support deleting payments, use the",
4634
- alternative: "Use createRefund() instead to refund payments"
4635
- });
4777
+ throw new ProviderNotSupportedError(
4778
+ "deletePayment",
4779
+ this.providerName,
4780
+ {
4781
+ reason: "GoPay does not support deleting payments, use the",
4782
+ alternative: "Use createRefund() instead to refund payments"
4783
+ }
4784
+ );
4636
4785
  };
4637
4786
  capturePayment = async (id, params) => {
4638
4787
  const payment = await this._client.get(
@@ -4640,32 +4789,39 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4640
4789
  { headers: await this.tokenManager.getAuthHeaders() }
4641
4790
  );
4642
4791
  if (!payment.ok) {
4643
- throw new OperationFailedError("capturePayment", this.providerName, {
4644
- cause: new Error("Failed to retrieve payment")
4645
- });
4792
+ throw new OperationFailedError(
4793
+ "capturePayment",
4794
+ this.providerName,
4795
+ {
4796
+ cause: new Error("Failed to retrieve payment")
4797
+ }
4798
+ );
4646
4799
  }
4647
4800
  const { item, qty } = JSON.parse(
4648
4801
  decodeHtmlEntities(
4649
- payment.value.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4802
+ payment.value.additional_params?.find(
4803
+ (param) => param.name === PAYKIT_METADATA_KEY
4804
+ )?.value ?? "{}"
4650
4805
  )
4651
4806
  );
4652
4807
  if (!payment) {
4653
- throw new OperationFailedError("capturePayment", this.providerName, {
4654
- cause: new Error("Payment not found after capture")
4655
- });
4808
+ throw new OperationFailedError(
4809
+ "capturePayment",
4810
+ this.providerName,
4811
+ {
4812
+ cause: new Error("Payment not found after capture")
4813
+ }
4814
+ );
4656
4815
  }
4657
4816
  const captureBody = {
4658
4817
  amount: params.amount,
4659
4818
  items: [{ name: item, amount: params.amount, count: qty }]
4660
4819
  };
4661
- await this._client.post(
4662
- `/payments/payment/${id}/capture`,
4663
- {
4664
- body: JSON.stringify(captureBody),
4665
- headers: await this.tokenManager.getAuthHeaders()
4666
- }
4667
- );
4668
- return paykitPayment$InboundSchema(payment.value);
4820
+ await this._client.post(`/payments/payment/${id}/capture`, {
4821
+ body: JSON.stringify(captureBody),
4822
+ headers: await this.tokenManager.getAuthHeaders()
4823
+ });
4824
+ return Payment$inboundSchema(payment.value);
4669
4825
  };
4670
4826
  cancelPayment = async (id) => {
4671
4827
  await this._client.post(
@@ -4674,9 +4830,13 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4674
4830
  );
4675
4831
  const payment = await this.retrievePayment(id);
4676
4832
  if (!payment) {
4677
- throw new OperationFailedError("cancelPayment", this.providerName, {
4678
- cause: new Error("Payment not found after cancellation")
4679
- });
4833
+ throw new OperationFailedError(
4834
+ "cancelPayment",
4835
+ this.providerName,
4836
+ {
4837
+ cause: new Error("Payment not found after cancellation")
4838
+ }
4839
+ );
4680
4840
  }
4681
4841
  return payment;
4682
4842
  };
@@ -4687,34 +4847,52 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4687
4847
  console.info("Gopay doesn't support updating payments");
4688
4848
  const existing = await this.retrievePayment(id);
4689
4849
  if (!existing) {
4690
- throw new OperationFailedError("updatePayment", this.providerName, {
4691
- cause: new Error("Failed to retrieve payment")
4692
- });
4850
+ throw new OperationFailedError(
4851
+ "updatePayment",
4852
+ this.providerName,
4853
+ {
4854
+ cause: new Error("Failed to retrieve payment")
4855
+ }
4856
+ );
4693
4857
  }
4694
4858
  return existing;
4695
4859
  };
4696
4860
  async createRefund(params) {
4697
4861
  const { error, data } = createRefundSchema.safeParse(params);
4698
4862
  if (error) {
4699
- throw ValidationError.fromZodError(error, this.providerName, "createRefund");
4863
+ throw ValidationError.fromZodError(
4864
+ error,
4865
+ this.providerName,
4866
+ "createRefund"
4867
+ );
4700
4868
  }
4701
4869
  const payment = await this.retrievePayment(data.payment_id);
4702
4870
  if (!payment) {
4703
- throw new OperationFailedError("createRefund", this.providerName, {
4704
- cause: new Error("Failed to retrieve payment")
4705
- });
4871
+ throw new OperationFailedError(
4872
+ "createRefund",
4873
+ this.providerName,
4874
+ {
4875
+ cause: new Error("Failed to retrieve payment")
4876
+ }
4877
+ );
4706
4878
  }
4707
4879
  const response = await this._client.post(`/payments/payment/${data.payment_id}/refund`, {
4708
- body: new URLSearchParams({ amount: String(data.amount) }).toString(),
4880
+ body: new URLSearchParams({
4881
+ amount: String(data.amount)
4882
+ }).toString(),
4709
4883
  headers: {
4710
4884
  ...await this.tokenManager.getAuthHeaders(),
4711
4885
  "Content-Type": "application/x-www-form-urlencoded"
4712
4886
  }
4713
4887
  });
4714
4888
  if (!response.ok) {
4715
- throw new OperationFailedError("createRefund", this.providerName, {
4716
- cause: new Error("Failed to create refund")
4717
- });
4889
+ throw new OperationFailedError(
4890
+ "createRefund",
4891
+ this.providerName,
4892
+ {
4893
+ cause: new Error("Failed to create refund")
4894
+ }
4895
+ );
4718
4896
  }
4719
4897
  return {
4720
4898
  id: crypto.randomBytes(8).toString("hex").slice(0, 15),
@@ -4724,23 +4902,28 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4724
4902
  metadata: data.metadata
4725
4903
  };
4726
4904
  }
4727
- handleWebhook = async (payload) => {
4905
+ handleWebhook = async (payload, webhookSecret) => {
4728
4906
  const { fullUrl } = payload;
4729
4907
  const paymentId = new URL(fullUrl).searchParams.get("id");
4730
4908
  const parentId = new URL(fullUrl).searchParams.get("parent_id");
4731
4909
  if (!paymentId) {
4732
- throw new WebhookError("Payment ID is required", { provider: this.providerName });
4910
+ throw new WebhookError("Payment ID is required", {
4911
+ provider: this.providerName
4912
+ });
4733
4913
  }
4734
4914
  if (this.opts.debug) {
4735
4915
  console.info("Received GoPay webhook for payment:", paymentId);
4736
4916
  }
4737
4917
  const [payment, error] = await tryCatchAsync(
4738
- this._client.get(`/payments/payment/${paymentId}`, {
4739
- headers: {
4740
- ...await this.tokenManager.getAuthHeaders(),
4741
- "Content-Type": "application/x-www-form-urlencoded"
4918
+ this._client.get(
4919
+ `/payments/payment/${paymentId}`,
4920
+ {
4921
+ headers: {
4922
+ ...await this.tokenManager.getAuthHeaders(),
4923
+ "Content-Type": "application/x-www-form-urlencoded"
4924
+ }
4742
4925
  }
4743
- })
4926
+ )
4744
4927
  );
4745
4928
  if (error) {
4746
4929
  throw new WebhookError("Failed to retrieve payment", {
@@ -4748,10 +4931,15 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4748
4931
  });
4749
4932
  }
4750
4933
  if (!payment.value) {
4751
- throw new WebhookError("Payment not found", { provider: this.providerName });
4934
+ throw new WebhookError("Payment not found", {
4935
+ provider: this.providerName
4936
+ });
4752
4937
  }
4753
4938
  if (this.opts.debug) {
4754
- console.info("Webhook verified successfully, status:", payment.value.state);
4939
+ console.info(
4940
+ "Webhook verified successfully, status:",
4941
+ payment.value.state
4942
+ );
4755
4943
  }
4756
4944
  const statusMap = {
4757
4945
  CREATED: "pending",
@@ -4770,7 +4958,7 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4770
4958
  __INDETERMINATE: (data) => {
4771
4959
  const isRefundEvent = data.state === "REFUNDED" || data.state === "PARTIALLY_REFUNDED";
4772
4960
  if (isRefundEvent) {
4773
- const refund = paykitRefund$InboundSchema(data);
4961
+ const refund = Refund$inboundSchema(data);
4774
4962
  return [
4775
4963
  paykitEvent$InboundSchema({
4776
4964
  type: "refund.created",
@@ -4783,7 +4971,7 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4783
4971
  return [];
4784
4972
  },
4785
4973
  pending: (data) => {
4786
- const payment2 = paykitPayment$InboundSchema(data);
4974
+ const payment2 = Payment$inboundSchema(data);
4787
4975
  return [
4788
4976
  paykitEvent$InboundSchema({
4789
4977
  type: "payment.created",
@@ -4794,7 +4982,7 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4794
4982
  ];
4795
4983
  },
4796
4984
  processing: (data) => {
4797
- const payment2 = paykitPayment$InboundSchema(data);
4985
+ const payment2 = Payment$inboundSchema(data);
4798
4986
  return [
4799
4987
  paykitEvent$InboundSchema({
4800
4988
  type: "payment.updated",
@@ -4805,7 +4993,7 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4805
4993
  ];
4806
4994
  },
4807
4995
  requires_capture: (data) => {
4808
- const payment2 = paykitPayment$InboundSchema(data);
4996
+ const payment2 = Payment$inboundSchema(data);
4809
4997
  return [
4810
4998
  paykitEvent$InboundSchema({
4811
4999
  type: "payment.updated",
@@ -4816,9 +5004,9 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4816
5004
  ];
4817
5005
  },
4818
5006
  canceled: (data) => {
4819
- const payment2 = paykitPayment$InboundSchema(data);
5007
+ const payment2 = Payment$inboundSchema(data);
4820
5008
  const isCancellingSubscription = parentId && data.recurrence?.recurrence_state == "STOPPED";
4821
- const subscription = paykitSubscription$InboundSchema(
5009
+ const subscription = Subscription$inboundSchema(
4822
5010
  data
4823
5011
  );
4824
5012
  const subscriptionCanceledWebhookEvent = {
@@ -4828,9 +5016,13 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4828
5016
  data: subscription
4829
5017
  };
4830
5018
  return [
4831
- ...isCancellingSubscription ? [paykitEvent$InboundSchema(subscriptionCanceledWebhookEvent)] : [],
5019
+ ...isCancellingSubscription ? [
5020
+ paykitEvent$InboundSchema(
5021
+ subscriptionCanceledWebhookEvent
5022
+ )
5023
+ ] : [],
4832
5024
  paykitEvent$InboundSchema({
4833
- type: "payment.canceled",
5025
+ type: "payment.failed",
4834
5026
  created: (/* @__PURE__ */ new Date()).getTime(),
4835
5027
  id: crypto.randomBytes(8).toString("hex").slice(0, 15),
4836
5028
  data: payment2
@@ -4838,10 +5030,10 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4838
5030
  ];
4839
5031
  },
4840
5032
  failed: (data) => {
4841
- const payment2 = paykitPayment$InboundSchema(data);
5033
+ const payment2 = Payment$inboundSchema(data);
4842
5034
  return [
4843
5035
  paykitEvent$InboundSchema({
4844
- type: "payment.canceled",
5036
+ type: "payment.failed",
4845
5037
  created: (/* @__PURE__ */ new Date()).getTime(),
4846
5038
  id: crypto.randomBytes(8).toString("hex").slice(0, 15),
4847
5039
  data: payment2
@@ -4849,9 +5041,9 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4849
5041
  ];
4850
5042
  },
4851
5043
  succeeded: (data) => {
4852
- const payment2 = paykitPayment$InboundSchema(data);
4853
- const invoice = paykitInvoice$InboundSchema(data, !!parentId);
4854
- const subscription = paykitSubscription$InboundSchema(
5044
+ const payment2 = Payment$inboundSchema(data);
5045
+ const invoice = Invoice$inboundSchema(data, !!parentId);
5046
+ const subscription = Subscription$inboundSchema(
4855
5047
  data
4856
5048
  );
4857
5049
  const subscriptionCreatedWebhookEvent = {
@@ -4861,7 +5053,11 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4861
5053
  data: subscription
4862
5054
  };
4863
5055
  return [
4864
- ...parentId ? [paykitEvent$InboundSchema(subscriptionCreatedWebhookEvent)] : [],
5056
+ ...parentId ? [
5057
+ paykitEvent$InboundSchema(
5058
+ subscriptionCreatedWebhookEvent
5059
+ )
5060
+ ] : [],
4865
5061
  paykitEvent$InboundSchema({
4866
5062
  type: "invoice.generated",
4867
5063
  created: (/* @__PURE__ */ new Date()).getTime(),
@@ -4869,7 +5065,7 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4869
5065
  data: invoice
4870
5066
  }),
4871
5067
  paykitEvent$InboundSchema({
4872
- type: "payment.created",
5068
+ type: "payment.succeeded",
4873
5069
  created: (/* @__PURE__ */ new Date()).getTime(),
4874
5070
  id: crypto.randomBytes(8).toString("hex").slice(0, 15),
4875
5071
  data: payment2
@@ -4877,7 +5073,7 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4877
5073
  ];
4878
5074
  },
4879
5075
  requires_action: (data) => {
4880
- const payment2 = paykitPayment$InboundSchema(data);
5076
+ const payment2 = Payment$inboundSchema(data);
4881
5077
  return [
4882
5078
  paykitEvent$InboundSchema({
4883
5079
  type: "payment.updated",