@paykit-sdk/gopay 1.0.5 → 1.1.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/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { schema, validateRequiredKeys, AbstractPayKitProvider, HTTPClient, createCheckoutSchema, ValidationError, InvalidTypeError, PAYKIT_METADATA_KEY, OperationFailedError, ProviderNotSupportedError, createSubscriptionSchema, createPaymentSchema, ConfigurationError, 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, ConfigurationError, createPaymentSchema, 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;
@@ -4036,70 +4036,63 @@ var ostring = () => stringType().optional();
4036
4036
  var onumber = () => numberType().optional();
4037
4037
  var oboolean = () => booleanType().optional();
4038
4038
  var coerce = {
4039
- string: (arg) => ZodString.create({ ...arg, coerce: true }),
4040
- number: (arg) => ZodNumber.create({ ...arg, coerce: true }),
4041
- boolean: (arg) => ZodBoolean.create({
4039
+ string: ((arg) => ZodString.create({ ...arg, coerce: true })),
4040
+ number: ((arg) => ZodNumber.create({ ...arg, coerce: true })),
4041
+ boolean: ((arg) => ZodBoolean.create({
4042
4042
  ...arg,
4043
4043
  coerce: true
4044
- }),
4045
- bigint: (arg) => ZodBigInt.create({ ...arg, coerce: true }),
4046
- date: (arg) => ZodDate.create({ ...arg, coerce: true })
4044
+ })),
4045
+ bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })),
4046
+ date: ((arg) => ZodDate.create({ ...arg, coerce: true }))
4047
4047
  };
4048
4048
  var NEVER = INVALID;
4049
- var AuthController = class {
4050
- constructor(opts) {
4051
- this.opts = opts;
4052
- const debug = opts.debug ?? true;
4053
- this._client = new HTTPClient({
4054
- baseUrl: this.opts.baseUrl,
4055
- headers: {},
4056
- retryOptions: { max: 3, baseDelay: 1e3, debug }
4057
- });
4058
- }
4059
- _client;
4060
- _accessToken = null;
4061
- getAccessToken = async () => {
4062
- if (this._accessToken) {
4063
- const [token, , expiryStr] = this._accessToken.split("::paykit::");
4064
- const expiry = parseInt(expiryStr || "0", 10);
4065
- if (expiry > Date.now()) return token;
4066
- }
4067
- const credentials = Buffer.from(
4068
- `${this.opts.clientId}:${this.opts.clientSecret}`
4069
- ).toString("base64");
4070
- const response = await this._client.post("/oauth2/token", {
4071
- headers: {
4072
- Authorization: `Basic ${credentials}`,
4073
- "Content-Type": "application/x-www-form-urlencoded"
4049
+ var decodeHtmlEntities = (str) => {
4050
+ return str.replace(/"/g, '"').replace(/'/g, "'").replace(/"/g, '"').replace(/'/g, "'");
4051
+ };
4052
+ var paykitPayment$InboundSchema = (data) => {
4053
+ const { item } = JSON.parse(
4054
+ decodeHtmlEntities(
4055
+ data.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4056
+ )
4057
+ );
4058
+ const metadata = omitInternalMetadata(
4059
+ data.additional_params?.reduce(
4060
+ (acc, param) => {
4061
+ acc[param.name] = String(param.value);
4062
+ return acc;
4074
4063
  },
4075
- body: new URLSearchParams({
4076
- grant_type: "client_credentials",
4077
- scope: "payment-all"
4078
- }).toString()
4079
- });
4080
- if (!response.ok || !response.value.access_token) {
4081
- throw new OperationFailedError("getAccessToken", "gopay", {
4082
- cause: new Error("Failed to obtain GoPay access token")
4083
- });
4084
- }
4085
- const expiryTime = Date.now() + (response.value.expires_in - 300) * 1e3;
4086
- const accessToken = `${response.value.access_token}::paykit::${expiryTime}`;
4087
- this._accessToken = accessToken;
4088
- return accessToken;
4064
+ {}
4065
+ ) ?? {}
4066
+ );
4067
+ const statusMap = {
4068
+ CREATED: "pending",
4069
+ PAYMENT_METHOD_CHOSEN: "processing",
4070
+ PAID: "succeeded",
4071
+ AUTHORIZED: "requires_capture",
4072
+ CANCELED: "canceled",
4073
+ TIMEOUTED: "canceled",
4074
+ REFUNDED: "canceled",
4075
+ PARTIALLY_REFUNDED: "canceled"
4089
4076
  };
4090
- getAuthHeaders = async () => {
4091
- const token = await this.getAccessToken();
4092
- return {
4093
- Authorization: `Bearer ${token}`,
4094
- "Content-Type": "application/json",
4095
- Accept: "application/json"
4096
- };
4077
+ const requiresAction = data.state === "CREATED" || data.state === "AUTHORIZED" ? true : false;
4078
+ return {
4079
+ id: data.id.toString(),
4080
+ amount: data.amount,
4081
+ currency: data.currency,
4082
+ customer: data.payer?.contact?.email ? { email: data.payer.contact.email } : "",
4083
+ status: statusMap[data.state],
4084
+ item_id: item,
4085
+ metadata,
4086
+ requires_action: requiresAction,
4087
+ payment_url: data.gw_url ?? null
4097
4088
  };
4098
4089
  };
4099
- var paykitPayment$InboundSchema = (data) => {
4100
- const itemId = JSON.parse(
4101
- data.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4102
- ).itemId;
4090
+ var paykitCheckout$InboundSchema = (data) => {
4091
+ const { item, qty, type } = JSON.parse(
4092
+ decodeHtmlEntities(
4093
+ data.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4094
+ )
4095
+ );
4103
4096
  const metadata = omitInternalMetadata(
4104
4097
  data.additional_params?.reduce(
4105
4098
  (acc, param) => {
@@ -4113,24 +4106,24 @@ var paykitPayment$InboundSchema = (data) => {
4113
4106
  id: data.id.toString(),
4114
4107
  amount: data.amount,
4115
4108
  currency: data.currency,
4116
- customer: data.payer ?? { email: data.payer?.email ?? "" },
4117
- status: data.state,
4118
- item_id: itemId,
4119
- metadata
4109
+ customer: data.payer?.contact?.email ? { email: data.payer.contact.email } : "",
4110
+ payment_url: data.gw_url ?? "",
4111
+ metadata,
4112
+ session_type: type,
4113
+ products: [{ id: item, quantity: parseInt(qty) }]
4120
4114
  };
4121
4115
  };
4122
4116
  var paykitInvoice$InboundSchema = (data, isSubscription) => {
4123
- const quantity = JSON.parse(
4124
- data.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4125
- ).qty;
4126
- const itemId = JSON.parse(
4127
- data.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4128
- ).itemId;
4117
+ const { item, qty } = JSON.parse(
4118
+ decodeHtmlEntities(
4119
+ data.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4120
+ )
4121
+ );
4129
4122
  const status = (() => {
4130
4123
  if (data.state === "PAID") return "paid";
4131
4124
  return "open";
4132
4125
  })();
4133
- const paidAt = isSubscription ? new Date(data.recurrence?.recurrence_date_from ?? "") : /* @__PURE__ */ new Date();
4126
+ const paidAt = isSubscription ? new Date(data.recurrence?.recurrence_date_to ?? "") : /* @__PURE__ */ new Date();
4134
4127
  const metadata = omitInternalMetadata(
4135
4128
  data.additional_params?.reduce(
4136
4129
  (acc, param) => {
@@ -4144,20 +4137,22 @@ var paykitInvoice$InboundSchema = (data, isSubscription) => {
4144
4137
  id: data.id.toString(),
4145
4138
  amount_paid: data.amount,
4146
4139
  currency: data.currency,
4147
- customer: data.payer ?? { email: data.payer?.email ?? "" },
4140
+ customer: data.payer?.contact?.email ? { email: data.payer.contact.email } : "",
4148
4141
  status,
4149
4142
  paid_at: paidAt.toISOString(),
4150
4143
  metadata: metadata ?? {},
4151
4144
  custom_fields: null,
4152
4145
  subscription_id: isSubscription ? data.id.toString() : null,
4153
4146
  billing_mode: isSubscription ? "recurring" : "one_time",
4154
- line_items: [{ id: itemId, quantity: parseInt(quantity) }]
4147
+ line_items: [{ id: item, quantity: parseInt(qty) }]
4155
4148
  };
4156
4149
  };
4157
4150
  var paykitSubscription$InboundSchema = (data) => {
4158
- const itemId = JSON.parse(
4159
- data.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4160
- ).itemId;
4151
+ const { item } = JSON.parse(
4152
+ decodeHtmlEntities(
4153
+ data.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4154
+ )
4155
+ );
4161
4156
  const billingIntervalMap = {
4162
4157
  DAY: "day",
4163
4158
  WEEK: "week",
@@ -4165,8 +4160,28 @@ var paykitSubscription$InboundSchema = (data) => {
4165
4160
  ON_DEMAND: "month"
4166
4161
  };
4167
4162
  const billingInterval = billingIntervalMap[data.recurrence?.recurrence_cycle ?? "ON_DEMAND"];
4168
- const currentPeriodStart = new Date(data.recurrence?.recurrence_date_from ?? "");
4163
+ const recurrencePeriod = data.recurrence?.recurrence_period ?? 1;
4164
+ const recurrenceCycle = data.recurrence?.recurrence_cycle;
4169
4165
  const currentPeriodEnd = new Date(data.recurrence?.recurrence_date_to ?? "");
4166
+ const currentPeriodStart = (() => {
4167
+ if (!currentPeriodEnd) return /* @__PURE__ */ new Date();
4168
+ const endDate = new Date(currentPeriodEnd);
4169
+ const startDate = new Date(endDate);
4170
+ switch (recurrenceCycle) {
4171
+ case "DAY":
4172
+ startDate.setDate(startDate.getDate() - recurrencePeriod);
4173
+ break;
4174
+ case "WEEK":
4175
+ startDate.setDate(startDate.getDate() - recurrencePeriod * 7);
4176
+ break;
4177
+ case "MONTH":
4178
+ startDate.setMonth(startDate.getMonth() - recurrencePeriod);
4179
+ break;
4180
+ default:
4181
+ startDate.setDate(startDate.getDate() - recurrencePeriod);
4182
+ }
4183
+ return startDate;
4184
+ })();
4170
4185
  const metadata = omitInternalMetadata(
4171
4186
  data.additional_params?.reduce(
4172
4187
  (acc, param) => {
@@ -4176,18 +4191,32 @@ var paykitSubscription$InboundSchema = (data) => {
4176
4191
  {}
4177
4192
  ) ?? {}
4178
4193
  );
4194
+ 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
+ })();
4179
4206
  return {
4180
4207
  id: data.id.toString(),
4181
- status: "active",
4182
- customer: data.payer ?? { email: data.payer?.email ?? "" },
4183
- item_id: itemId,
4208
+ status,
4209
+ customer: data.payer?.contact?.email ? { email: data.payer.contact.email } : "",
4210
+ item_id: item,
4184
4211
  billing_interval: billingInterval,
4185
4212
  currency: data.currency,
4186
4213
  amount: data.amount,
4187
- metadata: metadata ?? {},
4214
+ metadata,
4188
4215
  custom_fields: null,
4189
4216
  current_period_start: currentPeriodStart,
4190
- current_period_end: currentPeriodEnd
4217
+ current_period_end: currentPeriodEnd,
4218
+ requires_action: requiresAction,
4219
+ payment_url: requiresAction ? data.gw_url ?? null : null
4191
4220
  };
4192
4221
  };
4193
4222
  var paykitRefund$InboundSchema = (data) => {
@@ -4217,22 +4246,42 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4217
4246
  super(gopayOptionsSchema, opts, providerName);
4218
4247
  this.opts = opts;
4219
4248
  const debug = opts.debug ?? true;
4220
- this.baseUrl = opts.isSandbox ? "https://gate.gopay.cz/api" : "https://gw.sandbox.gopay.com/api";
4249
+ this.baseUrl = opts.isSandbox ? "https://gw.sandbox.gopay.com/api" : "https://gate.gopay.cz/api";
4221
4250
  this._client = new HTTPClient({
4222
4251
  baseUrl: this.baseUrl,
4223
4252
  headers: {},
4224
4253
  retryOptions: { max: 3, baseDelay: 1e3, debug }
4225
4254
  });
4226
- this.authController = new AuthController({ ...opts, baseUrl: this.baseUrl });
4255
+ this.tokenManager = new OAuth2TokenManager({
4256
+ client: this._client,
4257
+ provider: this.providerName,
4258
+ tokenEndpoint: "/oauth2/token",
4259
+ credentials: { username: opts.clientId, password: opts.clientSecret },
4260
+ responseAdapter: (response) => ({
4261
+ accessToken: response.access_token,
4262
+ expiresIn: response.expires_in
4263
+ }),
4264
+ expiryBuffer: 5 * 60,
4265
+ // 5 minutes
4266
+ requestBody: "grant_type=client_credentials&scope=payment-all",
4267
+ requestHeaders: {
4268
+ "Content-Type": "application/x-www-form-urlencoded",
4269
+ Accept: "application/json"
4270
+ },
4271
+ authHeaders: {
4272
+ "Content-Type": "application/json",
4273
+ Accept: "application/json"
4274
+ }
4275
+ });
4227
4276
  }
4228
4277
  providerName = providerName;
4229
4278
  _client;
4230
4279
  baseUrl;
4231
- authController;
4280
+ tokenManager;
4232
4281
  createCheckout = async (params) => {
4233
4282
  const { error, data } = createCheckoutSchema.safeParse(params);
4234
4283
  if (error) throw ValidationError.fromZodError(error, "gopay", "createCheckout");
4235
- if (typeof data.customer == "string" || typeof data.customer === "object" && !data.customer.email) {
4284
+ if (!isEmailCustomer(data.customer)) {
4236
4285
  throw new InvalidTypeError("customer", "object (customer) with email", "string", {
4237
4286
  provider: this.providerName,
4238
4287
  method: "createCheckout"
@@ -4245,7 +4294,7 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4245
4294
  );
4246
4295
  if (this.opts.debug) {
4247
4296
  console.info(
4248
- "Specify `lang` in the provider_metadata of createCheckout to set the language of the checkout, default is `EN`"
4297
+ "Specify `language` in the `provider_metadata` of createCheckout to set the language of the checkout, default is `EN`"
4249
4298
  );
4250
4299
  console.info("Creating checkout with metadata:", data.metadata);
4251
4300
  }
@@ -4274,31 +4323,42 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4274
4323
  type: "ITEM"
4275
4324
  }
4276
4325
  ],
4277
- lang: data.provider_metadata?.lang ? data.provider_metadata.lang : "EN",
4326
+ lang: data.provider_metadata?.language ? data.provider_metadata.language : "EN",
4278
4327
  callback: { return_url: data.success_url, notification_url: this.opts.webhookUrl },
4279
4328
  additional_params: Object.entries({
4280
4329
  ...data.metadata,
4281
4330
  [PAYKIT_METADATA_KEY]: JSON.stringify({
4282
- itemId: data.item_id,
4283
- qty: data.quantity
4331
+ item: data.item_id,
4332
+ qty: data.quantity,
4333
+ type: data.session_type
4284
4334
  })
4285
4335
  }).map(([name, value]) => ({
4286
4336
  name,
4287
4337
  value: String(value)
4288
4338
  }))
4289
4339
  };
4290
- const response = await this._client.post("/payments/payment", {
4291
- body: JSON.stringify(goPayRequest),
4292
- headers: await this.authController.getAuthHeaders()
4293
- });
4294
- console.dir({ response }, { depth: null });
4295
- return response.value;
4340
+ const response = await this._client.post(
4341
+ "/payments/payment",
4342
+ {
4343
+ body: JSON.stringify(goPayRequest),
4344
+ headers: await this.tokenManager.getAuthHeaders()
4345
+ }
4346
+ );
4347
+ if (!response.ok) {
4348
+ throw new OperationFailedError("createCheckout", this.providerName, {
4349
+ cause: new Error("Failed to create checkout")
4350
+ });
4351
+ }
4352
+ return paykitCheckout$InboundSchema(response.value);
4296
4353
  };
4297
4354
  retrieveCheckout = async (id) => {
4298
4355
  const response = await this._client.get(
4299
4356
  `/payments/payment/${id}`,
4300
4357
  {
4301
- headers: await this.authController.getAuthHeaders()
4358
+ headers: {
4359
+ ...await this.tokenManager.getAuthHeaders(),
4360
+ "Content-Type": "application/x-www-form-urlencoded"
4361
+ }
4302
4362
  }
4303
4363
  );
4304
4364
  if (!response.ok) {
@@ -4306,12 +4366,13 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4306
4366
  cause: new Error("Failed to retrieve checkout")
4307
4367
  });
4308
4368
  }
4309
- console.dir({ response }, { depth: null });
4310
- return response.value;
4369
+ return paykitCheckout$InboundSchema(response.value);
4311
4370
  };
4312
4371
  updateCheckout = async (id, params) => {
4313
4372
  if (this.opts.debug) {
4314
- console.info("Gopay doesn't support updating checkouts");
4373
+ console.info(
4374
+ "Gopay doesn't support updating checkouts, returning existing checkout"
4375
+ );
4315
4376
  }
4316
4377
  const existing = await this.retrieveCheckout(id);
4317
4378
  return existing;
@@ -4323,23 +4384,36 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4323
4384
  });
4324
4385
  };
4325
4386
  createCustomer = async (params) => {
4387
+ if (this.cloudClient) {
4388
+ return this.cloudClient.customers.create(params);
4389
+ }
4326
4390
  throw new ProviderNotSupportedError("createCustomer", "gopay", {
4327
- reason: "Gopay doesn't support creating customers"
4391
+ reason: "Gopay doesn't support creating customers, use the cloud API instead by setting `cloudApiKey` in the options"
4328
4392
  });
4329
4393
  };
4330
4394
  updateCustomer = async (id, params) => {
4395
+ if (this.cloudClient) {
4396
+ return this.cloudClient.customers.update(id, params);
4397
+ }
4331
4398
  throw new ProviderNotSupportedError("updateCustomer", "gopay", {
4332
- reason: "Gopay doesn't support updating customers"
4399
+ reason: "Gopay doesn't support updating customers, use the cloud API instead by setting `cloudApiKey` in the options"
4333
4400
  });
4334
4401
  };
4335
4402
  deleteCustomer = async (id) => {
4403
+ if (this.cloudClient) {
4404
+ this.cloudClient.customers.delete(id);
4405
+ return null;
4406
+ }
4336
4407
  throw new ProviderNotSupportedError("deleteCustomer", "gopay", {
4337
- reason: "Gopay doesn't support deleting customers"
4408
+ reason: "Gopay doesn't support deleting customers, use the cloud API instead by setting `cloudApiKey` in the options"
4338
4409
  });
4339
4410
  };
4340
4411
  retrieveCustomer = async (id) => {
4412
+ if (this.cloudClient) {
4413
+ return this.cloudClient.customers.retrieve(id);
4414
+ }
4341
4415
  throw new ProviderNotSupportedError("retrieveCustomer", "gopay", {
4342
- reason: "Gopay doesn't support retrieving customers"
4416
+ reason: "Gopay doesn't support retrieving customers, use the cloud API instead by setting `cloudApiKey` in the options"
4343
4417
  });
4344
4418
  };
4345
4419
  createSubscription = async (params) => {
@@ -4351,30 +4425,50 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4351
4425
  method: "createCheckout"
4352
4426
  });
4353
4427
  }
4354
- const { quantity, success_url } = validateRequiredKeys(
4355
- ["quantity", "success_url"],
4428
+ const { success_url } = validateRequiredKeys(
4429
+ ["success_url"],
4356
4430
  data.provider_metadata,
4357
4431
  "The following fields must be present in the provider_metadata of createCheckout: {keys}"
4358
4432
  );
4433
+ if (this.opts.debug) {
4434
+ if (data.billing_interval === "year") {
4435
+ console.info(
4436
+ "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"
4437
+ );
4438
+ }
4439
+ if (!data.provider_metadata?.description) {
4440
+ console.info(
4441
+ `No description provided for the subscription \`provider_metadata.description\`, using default description \`Subscription by ${data.customer.email}\``
4442
+ );
4443
+ }
4444
+ }
4359
4445
  const intervalMap = {
4360
4446
  day: "DAY",
4361
4447
  week: "WEEK",
4362
4448
  month: "MONTH",
4363
- year: "MONTH"
4449
+ year: "ON_DEMAND"
4364
4450
  };
4451
+ const recurrenceCycle = intervalMap?.[data.billing_interval] ?? "ON_DEMAND";
4365
4452
  const currentPeriodEnd = (() => {
4366
- if (data.billing_interval === "day") {
4453
+ if (recurrenceCycle === "DAY") {
4367
4454
  return new Date(Date.now() + 1 * 24 * 60 * 60 * 1e3).toISOString();
4368
4455
  }
4369
- if (data.billing_interval === "week") {
4456
+ if (recurrenceCycle === "WEEK") {
4370
4457
  return new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3).toISOString();
4371
4458
  }
4372
- if (data.billing_interval === "month") {
4459
+ if (recurrenceCycle === "MONTH") {
4373
4460
  return new Date(Date.now() + 30 * 24 * 60 * 60 * 1e3).toISOString();
4374
4461
  }
4375
- return new Date(Date.now() + 365 * 24 * 60 * 60 * 1e3).toISOString();
4462
+ if (recurrenceCycle === "ON_DEMAND") {
4463
+ throw new ConfigurationError(
4464
+ "ON_DEMAND subscriptions is not yet implemented by PayKit, please open an issue at https://github.com/usepaykit/paykit-sdk/issues",
4465
+ {
4466
+ provider: this.providerName
4467
+ }
4468
+ );
4469
+ }
4470
+ throw new Error("Invalid billing interval: " + data.billing_interval);
4376
4471
  })();
4377
- const recurrenceCycle = intervalMap[data.billing_interval] ?? "ON_DEMAND";
4378
4472
  const goPaySubscriptionOptions = {
4379
4473
  payer: {
4380
4474
  allowed_payment_instruments: ["PAYMENT_CARD"],
@@ -4385,54 +4479,66 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4385
4479
  amount: Number(data.amount),
4386
4480
  currency: data.currency ?? "CZK",
4387
4481
  order_number: crypto.randomBytes(8).toString("hex").slice(0, 15),
4388
- order_description: data.metadata?.description || "Subscription",
4389
- items: [
4390
- { name: data.item_id, amount: Number(data.amount), count: parseInt(quantity) }
4391
- ],
4482
+ order_description: data.provider_metadata?.description ? data.provider_metadata.description : "Subscription by " + data.customer.email,
4483
+ items: [{ name: data.item_id, amount: Number(data.amount), count: data.quantity }],
4392
4484
  recurrence: {
4393
4485
  recurrence_cycle: recurrenceCycle,
4394
- recurrence_period: parseInt(quantity),
4486
+ recurrence_period: data.quantity,
4395
4487
  recurrence_date_to: currentPeriodEnd
4396
4488
  },
4397
- callback: { return_url: success_url, notification_url: this.opts.webhookUrl }
4489
+ callback: { return_url: success_url, notification_url: this.opts.webhookUrl },
4490
+ additional_params: Object.entries({
4491
+ ...data.metadata,
4492
+ [PAYKIT_METADATA_KEY]: JSON.stringify({
4493
+ item: data.item_id,
4494
+ qty: data.quantity
4495
+ })
4496
+ }).map(([name, value]) => ({
4497
+ name,
4498
+ value: String(value)
4499
+ }))
4398
4500
  };
4399
- const response = await this._client.post("/payments/payment", {
4400
- body: JSON.stringify(goPaySubscriptionOptions),
4401
- headers: await this.authController.getAuthHeaders()
4402
- });
4501
+ const response = await this._client.post(
4502
+ "/payments/payment",
4503
+ {
4504
+ body: JSON.stringify(goPaySubscriptionOptions),
4505
+ headers: await this.tokenManager.getAuthHeaders()
4506
+ }
4507
+ );
4403
4508
  if (!response.ok) {
4404
4509
  throw new OperationFailedError("createSubscription", this.providerName, {
4405
4510
  cause: new Error("Failed to create subscription")
4406
4511
  });
4407
4512
  }
4408
- console.dir({ response }, { depth: 100 });
4409
- return response.value;
4513
+ return paykitSubscription$InboundSchema(response.value);
4410
4514
  };
4411
4515
  updateSubscription = async (id, params) => {
4412
- console.info("Gopay doesn't support updating subscriptions");
4413
4516
  const subscription = await this.retrieveSubscription(id);
4414
4517
  if (!subscription) {
4415
- throw new OperationFailedError("updateSubscription", this.providerName, {
4416
- cause: new Error("Failed to retrieve subscription")
4518
+ throw new ProviderNotSupportedError("updateSubscription", this.providerName, {
4519
+ reason: "Gopay doesn't support updating subscriptions",
4520
+ alternative: "Use the payment API instead and update the subscription manually"
4417
4521
  });
4418
4522
  }
4419
4523
  return subscription;
4420
4524
  };
4421
4525
  cancelSubscription = async (id) => {
4422
- const response = await this._client.post(
4423
- `/payments/payment/${id}/void-recurrence`,
4424
- {
4425
- headers: await this.authController.getAuthHeaders()
4426
- }
4427
- );
4428
- console.dir({ response }, { depth: 100 });
4429
- const subscription = await this.retrieveSubscription(id);
4430
- if (!subscription) {
4526
+ const existingSubscription = await this.retrieveSubscription(id);
4527
+ if (!existingSubscription) {
4431
4528
  throw new OperationFailedError("cancelSubscription", this.providerName, {
4432
4529
  cause: new Error("Failed to retrieve subscription")
4433
4530
  });
4434
4531
  }
4435
- return { ...subscription, status: "canceled" };
4532
+ const response = await this._client.post(`/payments/payment/${id}/void-recurrence`, {
4533
+ headers: {
4534
+ ...await this.tokenManager.getAuthHeaders(),
4535
+ "Content-Type": "application/x-www-form-urlencoded"
4536
+ }
4537
+ });
4538
+ return {
4539
+ ...existingSubscription,
4540
+ ...response.value?.result == "FINISHED" && { status: "canceled" }
4541
+ };
4436
4542
  };
4437
4543
  deleteSubscription = async (id) => {
4438
4544
  await this.cancelSubscription(id);
@@ -4442,7 +4548,7 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4442
4548
  const response = await this._client.get(
4443
4549
  `/payments/payment/${id}`,
4444
4550
  {
4445
- headers: await this.authController.getAuthHeaders()
4551
+ headers: await this.tokenManager.getAuthHeaders()
4446
4552
  }
4447
4553
  );
4448
4554
  if (!response.ok) {
@@ -4450,14 +4556,13 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4450
4556
  cause: new Error("Failed to retrieve subscription")
4451
4557
  });
4452
4558
  }
4453
- console.dir({ response }, { depth: 100 });
4454
- return response.value;
4559
+ return paykitSubscription$InboundSchema(response.value);
4455
4560
  };
4456
4561
  createPayment = async (params) => {
4457
4562
  const { error, data } = createPaymentSchema.safeParse(params);
4458
4563
  if (error)
4459
4564
  throw ValidationError.fromZodError(error, this.providerName, "createPayment");
4460
- if (typeof data.customer == "string" || typeof data.customer === "object" && !data.customer.email) {
4565
+ if (typeof data.customer == "string" || typeof data.customer === "object" && !data.customer?.email) {
4461
4566
  throw new InvalidTypeError("customer", "object (customer) with email", "string", {
4462
4567
  provider: this.providerName,
4463
4568
  method: "createPayment"
@@ -4494,23 +4599,28 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4494
4599
  value: String(value)
4495
4600
  }))
4496
4601
  };
4497
- const response = await this._client.post("/payments/payment", {
4498
- body: JSON.stringify(goPayRequest),
4499
- headers: await this.authController.getAuthHeaders()
4500
- });
4602
+ const response = await this._client.post(
4603
+ "/payments/payment",
4604
+ {
4605
+ body: JSON.stringify(goPayRequest),
4606
+ headers: await this.tokenManager.getAuthHeaders()
4607
+ }
4608
+ );
4501
4609
  if (!response.ok) {
4502
4610
  throw new OperationFailedError("createPayment", this.providerName, {
4503
4611
  cause: new Error("Failed to create payment")
4504
4612
  });
4505
4613
  }
4506
- console.dir({ response }, { depth: 100 });
4507
- return response.value;
4614
+ return paykitPayment$InboundSchema(response.value);
4508
4615
  };
4509
4616
  retrievePayment = async (id) => {
4510
4617
  const response = await this._client.get(
4511
4618
  `/payments/payment/${id}`,
4512
4619
  {
4513
- headers: await this.authController.getAuthHeaders()
4620
+ headers: {
4621
+ ...await this.tokenManager.getAuthHeaders(),
4622
+ "Content-Type": "application/x-www-form-urlencoded"
4623
+ }
4514
4624
  }
4515
4625
  );
4516
4626
  if (!response.ok) {
@@ -4518,8 +4628,7 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4518
4628
  cause: new Error("Failed to retrieve payment")
4519
4629
  });
4520
4630
  }
4521
- console.dir({ response }, { depth: 100 });
4522
- return response.value;
4631
+ return paykitPayment$InboundSchema(response.value);
4523
4632
  };
4524
4633
  deletePayment = async (id) => {
4525
4634
  throw new ProviderNotSupportedError("deletePayment", this.providerName, {
@@ -4529,22 +4638,19 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4529
4638
  };
4530
4639
  capturePayment = async (id, params) => {
4531
4640
  const payment = await this._client.get(
4532
- `/payments/payment/${id}`,
4533
- {
4534
- headers: await this.authController.getAuthHeaders()
4535
- }
4641
+ `/payments/payment/${id}/capture`,
4642
+ { headers: await this.tokenManager.getAuthHeaders() }
4536
4643
  );
4537
4644
  if (!payment.ok) {
4538
4645
  throw new OperationFailedError("capturePayment", this.providerName, {
4539
4646
  cause: new Error("Failed to retrieve payment")
4540
4647
  });
4541
4648
  }
4542
- const productId = JSON.parse(
4543
- payment.value.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4544
- ).itemId;
4545
- const quantity = JSON.parse(
4546
- payment.value.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4547
- ).qty;
4649
+ const { item, qty } = JSON.parse(
4650
+ decodeHtmlEntities(
4651
+ payment.value.additional_params?.find((param) => param.name === PAYKIT_METADATA_KEY)?.value ?? "{}"
4652
+ )
4653
+ );
4548
4654
  if (!payment) {
4549
4655
  throw new OperationFailedError("capturePayment", this.providerName, {
4550
4656
  cause: new Error("Payment not found after capture")
@@ -4552,22 +4658,22 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4552
4658
  }
4553
4659
  const captureBody = {
4554
4660
  amount: params.amount,
4555
- items: [{ name: productId, amount: params.amount, count: quantity }]
4661
+ items: [{ name: item, amount: params.amount, count: qty }]
4556
4662
  };
4557
- await this._client.post(`/payments/payment/${id}/capture`, {
4558
- body: JSON.stringify(captureBody),
4559
- headers: await this.authController.getAuthHeaders()
4560
- });
4663
+ await this._client.post(
4664
+ `/payments/payment/${id}/capture`,
4665
+ {
4666
+ body: JSON.stringify(captureBody),
4667
+ headers: await this.tokenManager.getAuthHeaders()
4668
+ }
4669
+ );
4561
4670
  return paykitPayment$InboundSchema(payment.value);
4562
4671
  };
4563
4672
  cancelPayment = async (id) => {
4564
- const response = await this._client.post(
4673
+ await this._client.post(
4565
4674
  `/payments/payment/${id}/void-authorization`,
4566
- {
4567
- headers: await this.authController.getAuthHeaders()
4568
- }
4675
+ { headers: await this.tokenManager.getAuthHeaders() }
4569
4676
  );
4570
- console.dir({ response }, { depth: 100 });
4571
4677
  const payment = await this.retrievePayment(id);
4572
4678
  if (!payment) {
4573
4679
  throw new OperationFailedError("cancelPayment", this.providerName, {
@@ -4591,24 +4697,22 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4591
4697
  };
4592
4698
  async createRefund(params) {
4593
4699
  const { error, data } = createRefundSchema.safeParse(params);
4594
- if (error)
4700
+ if (error) {
4595
4701
  throw ValidationError.fromZodError(error, this.providerName, "createRefund");
4702
+ }
4596
4703
  const payment = await this.retrievePayment(data.payment_id);
4597
4704
  if (!payment) {
4598
4705
  throw new OperationFailedError("createRefund", this.providerName, {
4599
4706
  cause: new Error("Failed to retrieve payment")
4600
4707
  });
4601
4708
  }
4602
- const response = await this._client.post(
4603
- `/payments/payment/${data.payment_id}/refund`,
4604
- {
4605
- body: new URLSearchParams({ amount: String(data.amount) }).toString(),
4606
- headers: {
4607
- ...await this.authController.getAuthHeaders(),
4608
- "Content-Type": "application/x-www-form-urlencoded"
4609
- }
4709
+ const response = await this._client.post(`/payments/payment/${data.payment_id}/refund`, {
4710
+ body: new URLSearchParams({ amount: String(data.amount) }).toString(),
4711
+ headers: {
4712
+ ...await this.tokenManager.getAuthHeaders(),
4713
+ "Content-Type": "application/x-www-form-urlencoded"
4610
4714
  }
4611
- );
4715
+ });
4612
4716
  if (!response.ok) {
4613
4717
  throw new OperationFailedError("createRefund", this.providerName, {
4614
4718
  cause: new Error("Failed to create refund")
@@ -4634,7 +4738,10 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4634
4738
  }
4635
4739
  const [payment, error] = await tryCatchAsync(
4636
4740
  this._client.get(`/payments/payment/${paymentId}`, {
4637
- headers: await this.authController.getAuthHeaders()
4741
+ headers: {
4742
+ ...await this.tokenManager.getAuthHeaders(),
4743
+ "Content-Type": "application/x-www-form-urlencoded"
4744
+ }
4638
4745
  })
4639
4746
  );
4640
4747
  if (error) {
@@ -4713,7 +4820,9 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4713
4820
  canceled: (data) => {
4714
4821
  const payment2 = paykitPayment$InboundSchema(data);
4715
4822
  const isCancellingSubscription = parentId && data.recurrence?.recurrence_state == "STOPPED";
4716
- const subscription = paykitSubscription$InboundSchema(data);
4823
+ const subscription = paykitSubscription$InboundSchema(
4824
+ data
4825
+ );
4717
4826
  const subscriptionCanceledWebhookEvent = {
4718
4827
  type: "subscription.canceled",
4719
4828
  created: (/* @__PURE__ */ new Date()).getTime(),
@@ -4744,7 +4853,9 @@ var GoPayProvider = class extends AbstractPayKitProvider {
4744
4853
  succeeded: (data) => {
4745
4854
  const payment2 = paykitPayment$InboundSchema(data);
4746
4855
  const invoice = paykitInvoice$InboundSchema(data, !!parentId);
4747
- const subscription = paykitSubscription$InboundSchema(data);
4856
+ const subscription = paykitSubscription$InboundSchema(
4857
+ data
4858
+ );
4748
4859
  const subscriptionCreatedWebhookEvent = {
4749
4860
  type: "subscription.created",
4750
4861
  created: (/* @__PURE__ */ new Date()).getTime(),
@@ -4804,9 +4915,10 @@ var gopay = () => {
4804
4915
  "GOPAY_CLIENT_SECRET",
4805
4916
  "GOPAY_GO_ID",
4806
4917
  "GOPAY_SANDBOX",
4807
- "GOPAY_WEBHOOK_URL"
4918
+ "GOPAY_WEBHOOK_URL",
4919
+ "PAYKIT_CLOUD_API_KEY"
4808
4920
  ],
4809
- process.env,
4921
+ process.env ?? { PAYKIT_CLOUD_API_KEY: "" },
4810
4922
  "Missing required environment variables: {keys}"
4811
4923
  );
4812
4924
  return createGopay({
@@ -4814,7 +4926,9 @@ var gopay = () => {
4814
4926
  clientSecret: envVars.GOPAY_CLIENT_SECRET,
4815
4927
  goId: envVars.GOPAY_GO_ID,
4816
4928
  isSandbox: envVars.GOPAY_SANDBOX === "true",
4817
- webhookUrl: envVars.GOPAY_WEBHOOK_URL
4929
+ webhookUrl: envVars.GOPAY_WEBHOOK_URL,
4930
+ cloudApiKey: envVars.PAYKIT_CLOUD_API_KEY,
4931
+ debug: true
4818
4932
  });
4819
4933
  };
4820
4934