@payclave/sdk-server 0.2.0 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @payclave/sdk-server
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Added
6
+
7
+ - `checkInvoiceRefund`, which asks Payclave's refund policy whether a refund would be accepted before you send it.
8
+ - `recordInvoiceRefundReference` accepts `destinationAddress` and `destinationReason`, and `externalTransactionHash` is optional (omit it in test mode). Refund adjustments include `verificationStatus`, `destinationAddress`, `destinationSource`, `riskFlags`, `senderAddress`, `verifiedAt`, `verificationFailureReason`, and `failedTransactionHash`.
9
+ - `invoice.refund_verified` and `invoice.refund_failed` webhook event types.
10
+
3
11
  ## 0.2.0
4
12
 
5
13
  ### Changed
package/README.md CHANGED
@@ -20,9 +20,9 @@ durable retries, and idempotent simulated fulfillment. It uses the published SDK
20
20
  ## Install
21
21
 
22
22
  ```bash
23
- npm install @payclave/sdk-server@0.2.0
23
+ npm install @payclave/sdk-server@0.3.0
24
24
  # or
25
- bun add @payclave/sdk-server@0.2.0
25
+ bun add @payclave/sdk-server@0.3.0
26
26
  ```
27
27
 
28
28
  ## Create a checkout session
@@ -164,7 +164,7 @@ const issued = await payclave.issueInvoice(draft.id, {
164
164
 
165
165
  The server calculates line totals and invoice totals at the settlement token's 6-decimal scale. `updateInvoiceDraft` replaces editable commercial fields and requires the latest `version`; `listInvoices` supports `limit`, `startingAfter`, and `collectionState`. Set `reminderSchedule` on the draft to schedule conservative before-due, due-date, and after-due reminders. Passing `send: true` to `issueInvoice` queues the issue email in the same durable workflow; `sendInvoice` resends it and `remindInvoice` queues a manual payment reminder. Invoice detail responses include immutable delivery history and the next scheduled reminder.
166
166
 
167
- For a partially paid invoice, `createInvoiceCheckoutSession` creates or reuses a checkout for the exact server-calculated remainder. Collection actions never move funds: `voidInvoiceRemaining` records the unpaid remainder as a write-off, and `recordInvoiceRefundReference` records a merchant-initiated external transaction without initiating a refund. Issued invoice responses include all checkout sessions, independently verified payments, and adjustment records.
167
+ For a partially paid invoice, `createInvoiceCheckoutSession` creates or reuses a checkout for the exact server-calculated remainder. Collection actions never move funds: `voidInvoiceRemaining` records the unpaid remainder as a write-off, and `recordInvoiceRefundReference` records a refund you sent, from your settlement wallet or another wallet such as an exchange account; Payclave never sends refunds. Call `checkInvoiceRefund` first: it reports whether the refund is allowed, whether it needs a `destinationReason`, and any warnings, such as a destination that is not the wallet the customer paid from or a refund of an overpayment. Where refund verification is available (always in test mode), the recorded adjustment starts as `verificationStatus: "pending"`, and Payclave verifies the transfer onchain before sending `invoice.refund_verified` or `invoice.refund_failed`. Issued invoice responses include all checkout sessions, independently verified payments, and adjustment records.
168
168
 
169
169
  `downloadInvoicePDF(id)` returns authenticated PDF bytes, a safe filename, and the request ID. The PDF is generated from the API's current server-side invoice snapshot; save or stream the returned bytes from trusted backend code.
170
170
 
@@ -245,7 +245,7 @@ The archive contains the versioned manifest, token-separated summary, invoice, p
245
245
 
246
246
  ### Webhook endpoints
247
247
 
248
- `createWebhookEndpoint` accepts a `url`, optional `eventTypes`, and `signal`. Supported event types are exported as `PAYCLAVE_WEBHOOK_EVENT_TYPES` and include invoice issue, paid, partial, past-due, overpayment, void, uncollectible, refund-reference, expiry, late payment after collection closure, payment-link completion and expiry, and payment failure events.
248
+ `createWebhookEndpoint` accepts a `url`, optional `eventTypes`, and `signal`. Supported event types are exported as `PAYCLAVE_WEBHOOK_EVENT_TYPES` and include invoice issue, paid, partial, past-due, overpayment, void, uncollectible, refund recorded, verified, and failed, expiry, late payment after collection closure, payment-link completion and expiry, and payment failure events.
249
249
 
250
250
  `getWebhookDelivery` returns the immutable event payload, replay lineage, and complete attempt timeline. Attempts include start/completion timestamps, duration, status, a stable error category, safe request-header evidence, and a sanitized response excerpt capped at 4 KB. `listWebhookDeliveryAttempts` returns that timeline directly. `replayWebhookDelivery` requires an `idempotencyKey`, creates a new delivery linked to the source, and preserves the original event ID and payload. Confirm that your handler deduplicates by event ID before replaying.
251
251
 
package/dist/index.cjs CHANGED
@@ -13,6 +13,8 @@ var PAYCLAVE_WEBHOOK_EVENT_TYPES = [
13
13
  "invoice.voided",
14
14
  "invoice.uncollectible",
15
15
  "invoice.refund_recorded",
16
+ "invoice.refund_verified",
17
+ "invoice.refund_failed",
16
18
  "invoice.payment_received_after_void",
17
19
  "invoice.payment_received_after_uncollectible",
18
20
  "invoice.expired",
@@ -180,7 +182,7 @@ var PayclaveError = class extends Error {
180
182
  }
181
183
  };
182
184
  var PAYCLAVE_SERVER_SDK_NAME = "payclave-sdk-server";
183
- var PAYCLAVE_SERVER_SDK_VERSION = "0.2.0";
185
+ var PAYCLAVE_SERVER_SDK_VERSION = "0.3.0";
184
186
  var defaultApiBaseUrl = "https://api.payclave.com";
185
187
  var defaultFetcher = (input, init) => fetch(input, init);
186
188
  var secretKeyPattern = /^sk_(test|live)_[A-Za-z0-9_-]+$/;
@@ -697,6 +699,7 @@ var isInvoice = (value) => {
697
699
  };
698
700
  var isInvoiceCheckoutSessionCreated = (value) => isRecord(value) && typeof value.invoiceId === "string" && typeof value.invoiceNumber === "string" && typeof value.checkoutSessionId === "string" && typeof value.checkoutUrl === "string" && typeof value.amountDue === "string" && typeof value.currencyCode === "string" && typeof value.expiresAt === "string";
699
701
  var isRefundReferenceResult = (value) => isRecord(value) && isRecord(value.adjustment) && isInvoice(value.invoice);
702
+ var isRefundDecision = (value) => isRecord(value) && typeof value.allowed === "boolean" && typeof value.requiresApproval === "boolean" && typeof value.refundableAmount === "string" && typeof value.overpaidAmount === "string" && Array.isArray(value.warnings);
700
703
  var isInvoiceList = (value) => isRecord(value) && Array.isArray(value.items) && value.items.every(isInvoice) && typeof value.hasMore === "boolean" && isStringOrNull(value.nextCursor);
701
704
  var isPaymentLinkCollect = (value) => isRecord(value) && typeof value.email === "boolean" && typeof value.name === "boolean" && typeof value.reference === "boolean";
702
705
  var isPaymentLink = (value) => isRecord(value) && typeof value.id === "string" && value.object === "payment_link" && typeof value.publicId === "string" && typeof value.url === "string" && typeof value.merchantId === "string" && typeof value.mode === "string" && typeof value.status === "string" && typeof value.version === "number" && typeof value.title === "string" && typeof value.description === "string" && (value.amountType === "fixed" || value.amountType === "customer_entered") && isStringOrNull(value.amount) && isStringOrNull(value.minimumAmount) && isStringOrNull(value.maximumAmount) && typeof value.currencyCode === "string" && typeof value.chainId === "number" && typeof value.tokenContract === "string" && (value.usageType === "single_use" || value.usageType === "reusable") && typeof value.completedPayments === "number" && typeof value.startedCheckouts === "number" && isStringOrNull(value.activeAt) && isStringOrNull(value.expiresAt) && isStringOrNull(value.pausedAt) && isStringOrNull(value.archivedAt) && isPaymentLinkCollect(value.collect) && typeof value.referencePrefix === "string" && isStringOrNull(value.successUrl) && isStringOrNull(value.cancelUrl) && typeof value.successMessage === "string" && isMetadata(value.metadata) && isStringOrNull(value.reservationInvoiceId) && isStringOrNull(value.reservedAt) && typeof value.createdAt === "string" && typeof value.updatedAt === "string" && isStringOrNull(value.lastCheckoutCreatedAt);
@@ -1167,6 +1170,19 @@ function createPayclaveServerClient({
1167
1170
  guard: isRefundReferenceResult
1168
1171
  });
1169
1172
  };
1173
+ const checkInvoiceRefund = (id, input) => {
1174
+ assertIdentifier(id, "Invoice id");
1175
+ assertIdentifier(input.paymentId, "Payment id");
1176
+ assertAmount(input.amount);
1177
+ const { signal, ...body } = input;
1178
+ return request({
1179
+ method: "POST",
1180
+ path: `/v1/invoices/${encodePathSegment(id)}/refund-checks`,
1181
+ body,
1182
+ signal,
1183
+ guard: isRefundDecision
1184
+ });
1185
+ };
1170
1186
  const createPaymentLink = (input) => {
1171
1187
  assertPaymentLinkFields(input);
1172
1188
  return request({
@@ -1594,6 +1610,7 @@ function createPayclaveServerClient({
1594
1610
  voidInvoiceRemaining,
1595
1611
  markInvoiceUncollectible,
1596
1612
  duplicateInvoice,
1613
+ checkInvoiceRefund,
1597
1614
  recordInvoiceRefundReference,
1598
1615
  createPaymentLink,
1599
1616
  listPaymentLinks,
package/dist/index.d.cts CHANGED
@@ -6,7 +6,7 @@ type PayclavePaymentStatus = "detected" | "validating" | "confirmed" | "failed"
6
6
  type PayclaveInvoiceCollectionState = "draft" | "open" | "past_due" | "partially_paid" | "paid" | "void" | "uncollectible" | (string & {});
7
7
  type PayclaveMigrationState = "current" | "review_required" | (string & {});
8
8
  type PayclaveSourceType = "api" | "dashboard" | "payment_link" | "sdk" | "legacy" | (string & {});
9
- declare const PAYCLAVE_WEBHOOK_EVENT_TYPES: readonly ["invoice.issued", "invoice.paid", "invoice.partially_paid", "invoice.past_due", "invoice.overpaid", "invoice.voided", "invoice.uncollectible", "invoice.refund_recorded", "invoice.payment_received_after_void", "invoice.payment_received_after_uncollectible", "invoice.expired", "payment_link.completed", "payment_link.expired", "payment.failed", "payment.underpaid", "payment.overpaid"];
9
+ declare const PAYCLAVE_WEBHOOK_EVENT_TYPES: readonly ["invoice.issued", "invoice.paid", "invoice.partially_paid", "invoice.past_due", "invoice.overpaid", "invoice.voided", "invoice.uncollectible", "invoice.refund_recorded", "invoice.refund_verified", "invoice.refund_failed", "invoice.payment_received_after_void", "invoice.payment_received_after_uncollectible", "invoice.expired", "payment_link.completed", "payment_link.expired", "payment.failed", "payment.underpaid", "payment.overpaid"];
10
10
  type PayclaveWebhookEventType = (typeof PAYCLAVE_WEBHOOK_EVENT_TYPES)[number];
11
11
  type PayclaveWebhookDeliveryStatus = "pending" | "delivering" | "delivered" | "retry_scheduled" | "failed" | (string & {});
12
12
  type PayclaveMetadata = Record<string, unknown>;
@@ -148,11 +148,34 @@ type RecordInvoiceRefundReferenceInput = PayclaveRequestOptions & {
148
148
  paymentId: string;
149
149
  amount: string;
150
150
  reason: string;
151
- externalTransactionHash: string;
151
+ /** Omit in test mode; Payclave simulates one. */
152
+ externalTransactionHash?: string;
152
153
  chainId: number;
153
154
  tokenContract: string;
155
+ /** Where the refund was sent. Optional when the payment has a verified paying wallet. */
156
+ destinationAddress?: string;
157
+ /** Required when destinationAddress is not the verified paying wallet. */
158
+ destinationReason?: string;
154
159
  idempotencyKey?: string;
155
160
  };
161
+ type CheckInvoiceRefundInput = PayclaveRequestOptions & {
162
+ paymentId: string;
163
+ amount: string;
164
+ destinationAddress: string;
165
+ };
166
+ type PayclaveRefundRiskCode = "different_destination" | "repeat_destination" | "overpayment" | "sent_from_other_wallet" | (string & {});
167
+ type PayclaveRefundDecision = {
168
+ allowed: boolean;
169
+ blockedReason?: string;
170
+ requiresApproval: boolean;
171
+ destinationSource?: "verified_payer" | "provided" | (string & {});
172
+ refundableAmount: string;
173
+ overpaidAmount: string;
174
+ warnings: Array<{
175
+ code: PayclaveRefundRiskCode;
176
+ message: string;
177
+ }>;
178
+ };
156
179
  type ListInvoicesInput = PayclaveRequestOptions & {
157
180
  limit?: number;
158
181
  startingAfter?: string;
@@ -592,6 +615,18 @@ type PayclavePaymentAdjustment = {
592
615
  externalTransactionHash?: string;
593
616
  chainId?: number;
594
617
  tokenContract?: string;
618
+ /** Refund references only: whether Payclave verified the transfer onchain. */
619
+ verificationStatus?: "unverified" | "pending" | "verified" | "failed" | (string & {});
620
+ destinationAddress?: string;
621
+ destinationSource?: "verified_payer" | "provided" | (string & {});
622
+ destinationReason?: string;
623
+ riskFlags?: PayclaveRefundRiskCode[];
624
+ /** Where a verified refund actually came from. */
625
+ senderAddress?: string;
626
+ verifiedAt?: string;
627
+ verificationFailureReason?: string;
628
+ /** A failed refund's hash, released so the transfer can be recorded again. */
629
+ failedTransactionHash?: string;
595
630
  createdByType: string;
596
631
  createdById: string;
597
632
  createdAt: string;
@@ -824,7 +859,7 @@ declare class PayclaveError extends Error {
824
859
  };
825
860
  }
826
861
  declare const PAYCLAVE_SERVER_SDK_NAME = "payclave-sdk-server";
827
- declare const PAYCLAVE_SERVER_SDK_VERSION = "0.2.0";
862
+ declare const PAYCLAVE_SERVER_SDK_VERSION = "0.3.0";
828
863
  declare function assertPayclaveWebhookSignature({ payload, signature, secret, toleranceSeconds, now, }: VerifyWebhookSignatureInput): void;
829
864
  declare function verifyPayclaveWebhookSignature(input: VerifyWebhookSignatureInput): boolean;
830
865
  declare function constructPayclaveWebhookEvent<TData extends PayclaveWebhookData = PayclaveWebhookData>(input: VerifyWebhookSignatureInput): PayclaveWebhookEvent<TData>;
@@ -845,6 +880,7 @@ declare function createPayclaveServerClient({ secretKey, apiBaseUrl, fetcher, ti
845
880
  voidInvoiceRemaining: (id: string, input?: InvoiceActionInput) => Promise<PayclaveInvoice>;
846
881
  markInvoiceUncollectible: (id: string, input?: InvoiceActionInput) => Promise<PayclaveInvoice>;
847
882
  duplicateInvoice: (id: string, input?: CreateInvoiceCheckoutSessionInput) => Promise<PayclaveInvoice>;
883
+ checkInvoiceRefund: (id: string, input: CheckInvoiceRefundInput) => Promise<PayclaveRefundDecision>;
848
884
  recordInvoiceRefundReference: (id: string, input: RecordInvoiceRefundReferenceInput) => Promise<PayclaveRefundReferenceResult>;
849
885
  createPaymentLink: (input: CreatePaymentLinkInput) => Promise<PayclavePaymentLink>;
850
886
  listPaymentLinks: (input?: ListPaymentLinksInput) => Promise<PayclavePaymentLinkList>;
@@ -885,4 +921,5 @@ declare function createPayclaveServerClient({ secretKey, apiBaseUrl, fetcher, ti
885
921
  };
886
922
  type PayclaveServerClient = ReturnType<typeof createPayclaveServerClient>;
887
923
 
888
- export { type CreateCheckoutSessionInput, type CreateInvoiceCheckoutSessionInput, type CreateInvoiceDraftInput, type CreateInvoiceInput, type CreatePaymentLinkInput, type CreateReconciliationExportInput, type CreateTestWebhookInput, type CreateWebhookEndpointInput, type GetReconciliationSummaryInput, type InvoiceActionInput, type IssueInvoiceInput, type ListInvoicesInput, type ListPaymentLinkPaymentsInput, type ListPaymentLinksInput, type ListReconciliationExportsInput, type ListWebhookDeliveriesInput, type ListWebhookIncidentsInput, PAYCLAVE_API_ERROR_CODES, PAYCLAVE_RECONCILIATION_SCHEMA_VERSION, PAYCLAVE_SERVER_SDK_ERROR_CODES, PAYCLAVE_SERVER_SDK_NAME, PAYCLAVE_SERVER_SDK_VERSION, PAYCLAVE_WEBHOOK_EVENT_TYPES, PAYCLAVE_WEBHOOK_VERIFICATION_ERROR_CODES, type PayclaveApiErrorCode, type PayclaveCheckoutSession, type PayclaveCreatedCheckoutSession, PayclaveError, type PayclaveErrorCode, type PayclaveFetcher, type PayclaveInvoice, type PayclaveInvoiceActivityEvent, type PayclaveInvoiceCheckoutSession, type PayclaveInvoiceCheckoutSessionCreated, type PayclaveInvoiceCollectionState, type PayclaveInvoiceCustomer, type PayclaveInvoiceDelivery, type PayclaveInvoiceDiscountInput, type PayclaveInvoiceDraftFields, type PayclaveInvoiceLineInput, type PayclaveInvoiceList, type PayclaveInvoicePDF, type PayclaveInvoicePayment, type PayclaveInvoiceReminderSchedule, type PayclaveInvoiceStatus, type PayclaveInvoiceTaxInput, type PayclaveMetadata, type PayclaveMigrationState, type PayclaveMode, type PayclavePayment, type PayclavePaymentAdjustment, type PayclavePaymentLink, type PayclavePaymentLinkAmountType, type PayclavePaymentLinkCollect, type PayclavePaymentLinkFields, type PayclavePaymentLinkList, type PayclavePaymentLinkPayments, type PayclavePaymentLinkStatus, type PayclavePaymentLinkUsageType, type PayclavePaymentSource, type PayclavePaymentStatus, type PayclaveReconciliationDateBasis, type PayclaveReconciliationDownload, type PayclaveReconciliationExport, type PayclaveReconciliationExportList, type PayclaveReconciliationExportStatus, type PayclaveReconciliationFile, type PayclaveReconciliationFilters, type PayclaveReconciliationSchema, type PayclaveReconciliationSummary, type PayclaveReconciliationTokenSummary, type PayclaveRefundReferenceResult, type PayclaveRequestOptions, type PayclaveServerClient, type PayclaveServerClientOptions, type PayclaveServerSdkErrorCode, type PayclaveSourceType, type PayclaveWebhookData, type PayclaveWebhookDelivery, type PayclaveWebhookDeliveryAttempt, type PayclaveWebhookDeliveryAttemptSummary, type PayclaveWebhookDeliveryStatus, type PayclaveWebhookEndpoint, type PayclaveWebhookEvent, type PayclaveWebhookEventType, type PayclaveWebhookIncident, type PayclaveWebhookSecretVersion, type PayclaveWebhookVerificationErrorCode, type PaymentLinkActionInput, type ReconciliationExportActionInput, type RecordInvoiceRefundReferenceInput, type ReleasePaymentLinkReservationInput, type ReplayWebhookDeliveryInput, type UpdateInvoiceDraftInput, type UpdatePaymentLinkInput, type UpdateWebhookEndpointInput, type VerifyWebhookSignatureInput, type WebhookEndpointActionInput, assertPayclaveWebhookSignature, constructPayclaveWebhookEvent, createPayclaveServerClient, verifyPayclaveWebhookSignature };
924
+ export { PAYCLAVE_API_ERROR_CODES, PAYCLAVE_RECONCILIATION_SCHEMA_VERSION, PAYCLAVE_SERVER_SDK_ERROR_CODES, PAYCLAVE_SERVER_SDK_NAME, PAYCLAVE_SERVER_SDK_VERSION, PAYCLAVE_WEBHOOK_EVENT_TYPES, PAYCLAVE_WEBHOOK_VERIFICATION_ERROR_CODES, PayclaveError, assertPayclaveWebhookSignature, constructPayclaveWebhookEvent, createPayclaveServerClient, verifyPayclaveWebhookSignature };
925
+ export type { CheckInvoiceRefundInput, CreateCheckoutSessionInput, CreateInvoiceCheckoutSessionInput, CreateInvoiceDraftInput, CreateInvoiceInput, CreatePaymentLinkInput, CreateReconciliationExportInput, CreateTestWebhookInput, CreateWebhookEndpointInput, GetReconciliationSummaryInput, InvoiceActionInput, IssueInvoiceInput, ListInvoicesInput, ListPaymentLinkPaymentsInput, ListPaymentLinksInput, ListReconciliationExportsInput, ListWebhookDeliveriesInput, ListWebhookIncidentsInput, PayclaveApiErrorCode, PayclaveCheckoutSession, PayclaveCreatedCheckoutSession, PayclaveErrorCode, PayclaveFetcher, PayclaveInvoice, PayclaveInvoiceActivityEvent, PayclaveInvoiceCheckoutSession, PayclaveInvoiceCheckoutSessionCreated, PayclaveInvoiceCollectionState, PayclaveInvoiceCustomer, PayclaveInvoiceDelivery, PayclaveInvoiceDiscountInput, PayclaveInvoiceDraftFields, PayclaveInvoiceLineInput, PayclaveInvoiceList, PayclaveInvoicePDF, PayclaveInvoicePayment, PayclaveInvoiceReminderSchedule, PayclaveInvoiceStatus, PayclaveInvoiceTaxInput, PayclaveMetadata, PayclaveMigrationState, PayclaveMode, PayclavePayment, PayclavePaymentAdjustment, PayclavePaymentLink, PayclavePaymentLinkAmountType, PayclavePaymentLinkCollect, PayclavePaymentLinkFields, PayclavePaymentLinkList, PayclavePaymentLinkPayments, PayclavePaymentLinkStatus, PayclavePaymentLinkUsageType, PayclavePaymentSource, PayclavePaymentStatus, PayclaveReconciliationDateBasis, PayclaveReconciliationDownload, PayclaveReconciliationExport, PayclaveReconciliationExportList, PayclaveReconciliationExportStatus, PayclaveReconciliationFile, PayclaveReconciliationFilters, PayclaveReconciliationSchema, PayclaveReconciliationSummary, PayclaveReconciliationTokenSummary, PayclaveRefundDecision, PayclaveRefundReferenceResult, PayclaveRefundRiskCode, PayclaveRequestOptions, PayclaveServerClient, PayclaveServerClientOptions, PayclaveServerSdkErrorCode, PayclaveSourceType, PayclaveWebhookData, PayclaveWebhookDelivery, PayclaveWebhookDeliveryAttempt, PayclaveWebhookDeliveryAttemptSummary, PayclaveWebhookDeliveryStatus, PayclaveWebhookEndpoint, PayclaveWebhookEvent, PayclaveWebhookEventType, PayclaveWebhookIncident, PayclaveWebhookSecretVersion, PayclaveWebhookVerificationErrorCode, PaymentLinkActionInput, ReconciliationExportActionInput, RecordInvoiceRefundReferenceInput, ReleasePaymentLinkReservationInput, ReplayWebhookDeliveryInput, UpdateInvoiceDraftInput, UpdatePaymentLinkInput, UpdateWebhookEndpointInput, VerifyWebhookSignatureInput, WebhookEndpointActionInput };
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@ type PayclavePaymentStatus = "detected" | "validating" | "confirmed" | "failed"
6
6
  type PayclaveInvoiceCollectionState = "draft" | "open" | "past_due" | "partially_paid" | "paid" | "void" | "uncollectible" | (string & {});
7
7
  type PayclaveMigrationState = "current" | "review_required" | (string & {});
8
8
  type PayclaveSourceType = "api" | "dashboard" | "payment_link" | "sdk" | "legacy" | (string & {});
9
- declare const PAYCLAVE_WEBHOOK_EVENT_TYPES: readonly ["invoice.issued", "invoice.paid", "invoice.partially_paid", "invoice.past_due", "invoice.overpaid", "invoice.voided", "invoice.uncollectible", "invoice.refund_recorded", "invoice.payment_received_after_void", "invoice.payment_received_after_uncollectible", "invoice.expired", "payment_link.completed", "payment_link.expired", "payment.failed", "payment.underpaid", "payment.overpaid"];
9
+ declare const PAYCLAVE_WEBHOOK_EVENT_TYPES: readonly ["invoice.issued", "invoice.paid", "invoice.partially_paid", "invoice.past_due", "invoice.overpaid", "invoice.voided", "invoice.uncollectible", "invoice.refund_recorded", "invoice.refund_verified", "invoice.refund_failed", "invoice.payment_received_after_void", "invoice.payment_received_after_uncollectible", "invoice.expired", "payment_link.completed", "payment_link.expired", "payment.failed", "payment.underpaid", "payment.overpaid"];
10
10
  type PayclaveWebhookEventType = (typeof PAYCLAVE_WEBHOOK_EVENT_TYPES)[number];
11
11
  type PayclaveWebhookDeliveryStatus = "pending" | "delivering" | "delivered" | "retry_scheduled" | "failed" | (string & {});
12
12
  type PayclaveMetadata = Record<string, unknown>;
@@ -148,11 +148,34 @@ type RecordInvoiceRefundReferenceInput = PayclaveRequestOptions & {
148
148
  paymentId: string;
149
149
  amount: string;
150
150
  reason: string;
151
- externalTransactionHash: string;
151
+ /** Omit in test mode; Payclave simulates one. */
152
+ externalTransactionHash?: string;
152
153
  chainId: number;
153
154
  tokenContract: string;
155
+ /** Where the refund was sent. Optional when the payment has a verified paying wallet. */
156
+ destinationAddress?: string;
157
+ /** Required when destinationAddress is not the verified paying wallet. */
158
+ destinationReason?: string;
154
159
  idempotencyKey?: string;
155
160
  };
161
+ type CheckInvoiceRefundInput = PayclaveRequestOptions & {
162
+ paymentId: string;
163
+ amount: string;
164
+ destinationAddress: string;
165
+ };
166
+ type PayclaveRefundRiskCode = "different_destination" | "repeat_destination" | "overpayment" | "sent_from_other_wallet" | (string & {});
167
+ type PayclaveRefundDecision = {
168
+ allowed: boolean;
169
+ blockedReason?: string;
170
+ requiresApproval: boolean;
171
+ destinationSource?: "verified_payer" | "provided" | (string & {});
172
+ refundableAmount: string;
173
+ overpaidAmount: string;
174
+ warnings: Array<{
175
+ code: PayclaveRefundRiskCode;
176
+ message: string;
177
+ }>;
178
+ };
156
179
  type ListInvoicesInput = PayclaveRequestOptions & {
157
180
  limit?: number;
158
181
  startingAfter?: string;
@@ -592,6 +615,18 @@ type PayclavePaymentAdjustment = {
592
615
  externalTransactionHash?: string;
593
616
  chainId?: number;
594
617
  tokenContract?: string;
618
+ /** Refund references only: whether Payclave verified the transfer onchain. */
619
+ verificationStatus?: "unverified" | "pending" | "verified" | "failed" | (string & {});
620
+ destinationAddress?: string;
621
+ destinationSource?: "verified_payer" | "provided" | (string & {});
622
+ destinationReason?: string;
623
+ riskFlags?: PayclaveRefundRiskCode[];
624
+ /** Where a verified refund actually came from. */
625
+ senderAddress?: string;
626
+ verifiedAt?: string;
627
+ verificationFailureReason?: string;
628
+ /** A failed refund's hash, released so the transfer can be recorded again. */
629
+ failedTransactionHash?: string;
595
630
  createdByType: string;
596
631
  createdById: string;
597
632
  createdAt: string;
@@ -824,7 +859,7 @@ declare class PayclaveError extends Error {
824
859
  };
825
860
  }
826
861
  declare const PAYCLAVE_SERVER_SDK_NAME = "payclave-sdk-server";
827
- declare const PAYCLAVE_SERVER_SDK_VERSION = "0.2.0";
862
+ declare const PAYCLAVE_SERVER_SDK_VERSION = "0.3.0";
828
863
  declare function assertPayclaveWebhookSignature({ payload, signature, secret, toleranceSeconds, now, }: VerifyWebhookSignatureInput): void;
829
864
  declare function verifyPayclaveWebhookSignature(input: VerifyWebhookSignatureInput): boolean;
830
865
  declare function constructPayclaveWebhookEvent<TData extends PayclaveWebhookData = PayclaveWebhookData>(input: VerifyWebhookSignatureInput): PayclaveWebhookEvent<TData>;
@@ -845,6 +880,7 @@ declare function createPayclaveServerClient({ secretKey, apiBaseUrl, fetcher, ti
845
880
  voidInvoiceRemaining: (id: string, input?: InvoiceActionInput) => Promise<PayclaveInvoice>;
846
881
  markInvoiceUncollectible: (id: string, input?: InvoiceActionInput) => Promise<PayclaveInvoice>;
847
882
  duplicateInvoice: (id: string, input?: CreateInvoiceCheckoutSessionInput) => Promise<PayclaveInvoice>;
883
+ checkInvoiceRefund: (id: string, input: CheckInvoiceRefundInput) => Promise<PayclaveRefundDecision>;
848
884
  recordInvoiceRefundReference: (id: string, input: RecordInvoiceRefundReferenceInput) => Promise<PayclaveRefundReferenceResult>;
849
885
  createPaymentLink: (input: CreatePaymentLinkInput) => Promise<PayclavePaymentLink>;
850
886
  listPaymentLinks: (input?: ListPaymentLinksInput) => Promise<PayclavePaymentLinkList>;
@@ -885,4 +921,5 @@ declare function createPayclaveServerClient({ secretKey, apiBaseUrl, fetcher, ti
885
921
  };
886
922
  type PayclaveServerClient = ReturnType<typeof createPayclaveServerClient>;
887
923
 
888
- export { type CreateCheckoutSessionInput, type CreateInvoiceCheckoutSessionInput, type CreateInvoiceDraftInput, type CreateInvoiceInput, type CreatePaymentLinkInput, type CreateReconciliationExportInput, type CreateTestWebhookInput, type CreateWebhookEndpointInput, type GetReconciliationSummaryInput, type InvoiceActionInput, type IssueInvoiceInput, type ListInvoicesInput, type ListPaymentLinkPaymentsInput, type ListPaymentLinksInput, type ListReconciliationExportsInput, type ListWebhookDeliveriesInput, type ListWebhookIncidentsInput, PAYCLAVE_API_ERROR_CODES, PAYCLAVE_RECONCILIATION_SCHEMA_VERSION, PAYCLAVE_SERVER_SDK_ERROR_CODES, PAYCLAVE_SERVER_SDK_NAME, PAYCLAVE_SERVER_SDK_VERSION, PAYCLAVE_WEBHOOK_EVENT_TYPES, PAYCLAVE_WEBHOOK_VERIFICATION_ERROR_CODES, type PayclaveApiErrorCode, type PayclaveCheckoutSession, type PayclaveCreatedCheckoutSession, PayclaveError, type PayclaveErrorCode, type PayclaveFetcher, type PayclaveInvoice, type PayclaveInvoiceActivityEvent, type PayclaveInvoiceCheckoutSession, type PayclaveInvoiceCheckoutSessionCreated, type PayclaveInvoiceCollectionState, type PayclaveInvoiceCustomer, type PayclaveInvoiceDelivery, type PayclaveInvoiceDiscountInput, type PayclaveInvoiceDraftFields, type PayclaveInvoiceLineInput, type PayclaveInvoiceList, type PayclaveInvoicePDF, type PayclaveInvoicePayment, type PayclaveInvoiceReminderSchedule, type PayclaveInvoiceStatus, type PayclaveInvoiceTaxInput, type PayclaveMetadata, type PayclaveMigrationState, type PayclaveMode, type PayclavePayment, type PayclavePaymentAdjustment, type PayclavePaymentLink, type PayclavePaymentLinkAmountType, type PayclavePaymentLinkCollect, type PayclavePaymentLinkFields, type PayclavePaymentLinkList, type PayclavePaymentLinkPayments, type PayclavePaymentLinkStatus, type PayclavePaymentLinkUsageType, type PayclavePaymentSource, type PayclavePaymentStatus, type PayclaveReconciliationDateBasis, type PayclaveReconciliationDownload, type PayclaveReconciliationExport, type PayclaveReconciliationExportList, type PayclaveReconciliationExportStatus, type PayclaveReconciliationFile, type PayclaveReconciliationFilters, type PayclaveReconciliationSchema, type PayclaveReconciliationSummary, type PayclaveReconciliationTokenSummary, type PayclaveRefundReferenceResult, type PayclaveRequestOptions, type PayclaveServerClient, type PayclaveServerClientOptions, type PayclaveServerSdkErrorCode, type PayclaveSourceType, type PayclaveWebhookData, type PayclaveWebhookDelivery, type PayclaveWebhookDeliveryAttempt, type PayclaveWebhookDeliveryAttemptSummary, type PayclaveWebhookDeliveryStatus, type PayclaveWebhookEndpoint, type PayclaveWebhookEvent, type PayclaveWebhookEventType, type PayclaveWebhookIncident, type PayclaveWebhookSecretVersion, type PayclaveWebhookVerificationErrorCode, type PaymentLinkActionInput, type ReconciliationExportActionInput, type RecordInvoiceRefundReferenceInput, type ReleasePaymentLinkReservationInput, type ReplayWebhookDeliveryInput, type UpdateInvoiceDraftInput, type UpdatePaymentLinkInput, type UpdateWebhookEndpointInput, type VerifyWebhookSignatureInput, type WebhookEndpointActionInput, assertPayclaveWebhookSignature, constructPayclaveWebhookEvent, createPayclaveServerClient, verifyPayclaveWebhookSignature };
924
+ export { PAYCLAVE_API_ERROR_CODES, PAYCLAVE_RECONCILIATION_SCHEMA_VERSION, PAYCLAVE_SERVER_SDK_ERROR_CODES, PAYCLAVE_SERVER_SDK_NAME, PAYCLAVE_SERVER_SDK_VERSION, PAYCLAVE_WEBHOOK_EVENT_TYPES, PAYCLAVE_WEBHOOK_VERIFICATION_ERROR_CODES, PayclaveError, assertPayclaveWebhookSignature, constructPayclaveWebhookEvent, createPayclaveServerClient, verifyPayclaveWebhookSignature };
925
+ export type { CheckInvoiceRefundInput, CreateCheckoutSessionInput, CreateInvoiceCheckoutSessionInput, CreateInvoiceDraftInput, CreateInvoiceInput, CreatePaymentLinkInput, CreateReconciliationExportInput, CreateTestWebhookInput, CreateWebhookEndpointInput, GetReconciliationSummaryInput, InvoiceActionInput, IssueInvoiceInput, ListInvoicesInput, ListPaymentLinkPaymentsInput, ListPaymentLinksInput, ListReconciliationExportsInput, ListWebhookDeliveriesInput, ListWebhookIncidentsInput, PayclaveApiErrorCode, PayclaveCheckoutSession, PayclaveCreatedCheckoutSession, PayclaveErrorCode, PayclaveFetcher, PayclaveInvoice, PayclaveInvoiceActivityEvent, PayclaveInvoiceCheckoutSession, PayclaveInvoiceCheckoutSessionCreated, PayclaveInvoiceCollectionState, PayclaveInvoiceCustomer, PayclaveInvoiceDelivery, PayclaveInvoiceDiscountInput, PayclaveInvoiceDraftFields, PayclaveInvoiceLineInput, PayclaveInvoiceList, PayclaveInvoicePDF, PayclaveInvoicePayment, PayclaveInvoiceReminderSchedule, PayclaveInvoiceStatus, PayclaveInvoiceTaxInput, PayclaveMetadata, PayclaveMigrationState, PayclaveMode, PayclavePayment, PayclavePaymentAdjustment, PayclavePaymentLink, PayclavePaymentLinkAmountType, PayclavePaymentLinkCollect, PayclavePaymentLinkFields, PayclavePaymentLinkList, PayclavePaymentLinkPayments, PayclavePaymentLinkStatus, PayclavePaymentLinkUsageType, PayclavePaymentSource, PayclavePaymentStatus, PayclaveReconciliationDateBasis, PayclaveReconciliationDownload, PayclaveReconciliationExport, PayclaveReconciliationExportList, PayclaveReconciliationExportStatus, PayclaveReconciliationFile, PayclaveReconciliationFilters, PayclaveReconciliationSchema, PayclaveReconciliationSummary, PayclaveReconciliationTokenSummary, PayclaveRefundDecision, PayclaveRefundReferenceResult, PayclaveRefundRiskCode, PayclaveRequestOptions, PayclaveServerClient, PayclaveServerClientOptions, PayclaveServerSdkErrorCode, PayclaveSourceType, PayclaveWebhookData, PayclaveWebhookDelivery, PayclaveWebhookDeliveryAttempt, PayclaveWebhookDeliveryAttemptSummary, PayclaveWebhookDeliveryStatus, PayclaveWebhookEndpoint, PayclaveWebhookEvent, PayclaveWebhookEventType, PayclaveWebhookIncident, PayclaveWebhookSecretVersion, PayclaveWebhookVerificationErrorCode, PaymentLinkActionInput, ReconciliationExportActionInput, RecordInvoiceRefundReferenceInput, ReleasePaymentLinkReservationInput, ReplayWebhookDeliveryInput, UpdateInvoiceDraftInput, UpdatePaymentLinkInput, UpdateWebhookEndpointInput, VerifyWebhookSignatureInput, WebhookEndpointActionInput };
package/dist/index.js CHANGED
@@ -11,6 +11,8 @@ var PAYCLAVE_WEBHOOK_EVENT_TYPES = [
11
11
  "invoice.voided",
12
12
  "invoice.uncollectible",
13
13
  "invoice.refund_recorded",
14
+ "invoice.refund_verified",
15
+ "invoice.refund_failed",
14
16
  "invoice.payment_received_after_void",
15
17
  "invoice.payment_received_after_uncollectible",
16
18
  "invoice.expired",
@@ -178,7 +180,7 @@ var PayclaveError = class extends Error {
178
180
  }
179
181
  };
180
182
  var PAYCLAVE_SERVER_SDK_NAME = "payclave-sdk-server";
181
- var PAYCLAVE_SERVER_SDK_VERSION = "0.2.0";
183
+ var PAYCLAVE_SERVER_SDK_VERSION = "0.3.0";
182
184
  var defaultApiBaseUrl = "https://api.payclave.com";
183
185
  var defaultFetcher = (input, init) => fetch(input, init);
184
186
  var secretKeyPattern = /^sk_(test|live)_[A-Za-z0-9_-]+$/;
@@ -695,6 +697,7 @@ var isInvoice = (value) => {
695
697
  };
696
698
  var isInvoiceCheckoutSessionCreated = (value) => isRecord(value) && typeof value.invoiceId === "string" && typeof value.invoiceNumber === "string" && typeof value.checkoutSessionId === "string" && typeof value.checkoutUrl === "string" && typeof value.amountDue === "string" && typeof value.currencyCode === "string" && typeof value.expiresAt === "string";
697
699
  var isRefundReferenceResult = (value) => isRecord(value) && isRecord(value.adjustment) && isInvoice(value.invoice);
700
+ var isRefundDecision = (value) => isRecord(value) && typeof value.allowed === "boolean" && typeof value.requiresApproval === "boolean" && typeof value.refundableAmount === "string" && typeof value.overpaidAmount === "string" && Array.isArray(value.warnings);
698
701
  var isInvoiceList = (value) => isRecord(value) && Array.isArray(value.items) && value.items.every(isInvoice) && typeof value.hasMore === "boolean" && isStringOrNull(value.nextCursor);
699
702
  var isPaymentLinkCollect = (value) => isRecord(value) && typeof value.email === "boolean" && typeof value.name === "boolean" && typeof value.reference === "boolean";
700
703
  var isPaymentLink = (value) => isRecord(value) && typeof value.id === "string" && value.object === "payment_link" && typeof value.publicId === "string" && typeof value.url === "string" && typeof value.merchantId === "string" && typeof value.mode === "string" && typeof value.status === "string" && typeof value.version === "number" && typeof value.title === "string" && typeof value.description === "string" && (value.amountType === "fixed" || value.amountType === "customer_entered") && isStringOrNull(value.amount) && isStringOrNull(value.minimumAmount) && isStringOrNull(value.maximumAmount) && typeof value.currencyCode === "string" && typeof value.chainId === "number" && typeof value.tokenContract === "string" && (value.usageType === "single_use" || value.usageType === "reusable") && typeof value.completedPayments === "number" && typeof value.startedCheckouts === "number" && isStringOrNull(value.activeAt) && isStringOrNull(value.expiresAt) && isStringOrNull(value.pausedAt) && isStringOrNull(value.archivedAt) && isPaymentLinkCollect(value.collect) && typeof value.referencePrefix === "string" && isStringOrNull(value.successUrl) && isStringOrNull(value.cancelUrl) && typeof value.successMessage === "string" && isMetadata(value.metadata) && isStringOrNull(value.reservationInvoiceId) && isStringOrNull(value.reservedAt) && typeof value.createdAt === "string" && typeof value.updatedAt === "string" && isStringOrNull(value.lastCheckoutCreatedAt);
@@ -1165,6 +1168,19 @@ function createPayclaveServerClient({
1165
1168
  guard: isRefundReferenceResult
1166
1169
  });
1167
1170
  };
1171
+ const checkInvoiceRefund = (id, input) => {
1172
+ assertIdentifier(id, "Invoice id");
1173
+ assertIdentifier(input.paymentId, "Payment id");
1174
+ assertAmount(input.amount);
1175
+ const { signal, ...body } = input;
1176
+ return request({
1177
+ method: "POST",
1178
+ path: `/v1/invoices/${encodePathSegment(id)}/refund-checks`,
1179
+ body,
1180
+ signal,
1181
+ guard: isRefundDecision
1182
+ });
1183
+ };
1168
1184
  const createPaymentLink = (input) => {
1169
1185
  assertPaymentLinkFields(input);
1170
1186
  return request({
@@ -1592,6 +1608,7 @@ function createPayclaveServerClient({
1592
1608
  voidInvoiceRemaining,
1593
1609
  markInvoiceUncollectible,
1594
1610
  duplicateInvoice,
1611
+ checkInvoiceRefund,
1595
1612
  recordInvoiceRefundReference,
1596
1613
  createPaymentLink,
1597
1614
  listPaymentLinks,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payclave/sdk-server",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "TypeScript server SDK for Payclave non-custodial crypto checkout.",
5
5
  "keywords": [
6
6
  "payclave",
@@ -52,9 +52,9 @@
52
52
  "prepublishOnly": "bun run lint && bun run typecheck && bun run test && bun run build && bun run pack:check"
53
53
  },
54
54
  "devDependencies": {
55
- "@biomejs/biome": "^2.4.15",
56
- "bun-types": "^1.3.14",
57
- "tsup": "^8.5.1",
55
+ "@biomejs/biome": "^2.6.4",
56
+ "bun-types": "^1.4.4",
57
+ "tsup": "^9.0.0",
58
58
  "typescript": "^6.0.3"
59
59
  }
60
60
  }