diff --git a/src/binders/payments/captures/PaymentCapturesBinder.ts b/src/binders/payments/captures/PaymentCapturesBinder.ts index 2bec810e..6a24757e 100644 --- a/src/binders/payments/captures/PaymentCapturesBinder.ts +++ b/src/binders/payments/captures/PaymentCapturesBinder.ts @@ -8,7 +8,7 @@ import checkId from '../../../plumbing/checkId'; import renege from '../../../plumbing/renege'; import type Callback from '../../../types/Callback'; import Binder from '../../Binder'; -import { type GetParameters, type IterateParameters, type PageParameters } from './parameters'; +import { type CreateParameters, type GetParameters, type IterateParameters, type PageParameters } from './parameters'; function getPathSegments(paymentId: string) { return `payments/${paymentId}/captures`; @@ -20,11 +20,27 @@ export default class PaymentCapturesBinder extends Binder alias(this, { page: ['all', 'list'] }); } + /** + * Capture an *authorized* payment. + * + * @since 4.1.0 + * @see https://docs.mollie.com/reference/create-capture + */ + public create(parameters: CreateParameters): Promise; + public create(parameters: CreateParameters, callback: Callback): void; + public create(parameters: CreateParameters) { + if (renege(this, this.create, ...arguments)) return; + const { paymentId, ...data } = parameters; + if (!checkId(paymentId, 'payment')) { + throw new ApiError('The payment id is invalid'); + } + return this.networkClient.post(getPathSegments(paymentId), data); + } + /** * Retrieve a single capture by its ID. Note the original payment's ID is needed as well. * - * Captures are used for payments that have the *authorize-then-capture* flow. The only payment methods at the moment that have this flow are **Klarna Pay now**, **Klarna Pay later** and **Klarna - * Slice it**. + * Captures are used for payments that have the *authorize-then-capture* flow. Mollie currently supports captures for **Cards** and **Klarna**. * * @since 1.1.1 * @see https://docs.mollie.com/reference/v2/captures-api/get-capture @@ -46,8 +62,7 @@ export default class PaymentCapturesBinder extends Binder /** * Retrieve all captures for a certain payment. * - * Captures are used for payments that have the *authorize-then-capture* flow. The only payment methods at the moment that have this flow are *Klarna Pay now*, *Klarna Pay later* and *Klarna Slice - * it*. + * Captures are used for payments that have the *authorize-then-capture* flow. Mollie currently supports captures for **Cards** and **Klarna**. * * @since 3.0.0 * @see https://docs.mollie.com/reference/v2/captures-api/list-captures @@ -66,8 +81,7 @@ export default class PaymentCapturesBinder extends Binder /** * Retrieve all captures for a certain payment. * - * Captures are used for payments that have the *authorize-then-capture* flow. The only payment methods at the moment that have this flow are *Klarna Pay now*, *Klarna Pay later* and *Klarna Slice - * it*. + * Captures are used for payments that have the *authorize-then-capture* flow. Mollie currently supports captures for **Cards** and **Klarna**. * * @since 3.6.0 * @see https://docs.mollie.com/reference/v2/captures-api/list-captures diff --git a/src/binders/payments/captures/parameters.ts b/src/binders/payments/captures/parameters.ts index d4a52d69..38faf2fb 100644 --- a/src/binders/payments/captures/parameters.ts +++ b/src/binders/payments/captures/parameters.ts @@ -1,18 +1,22 @@ -import { type CaptureEmbed } from '../../../data/payments/captures/data'; -import { type PaginationParameters, type ThrottlingParameter } from '../../../types/parameters'; +import { type CaptureData, type CaptureInclude } from '../../../data/payments/captures/data'; +import { type IdempotencyParameter, type PaginationParameters, type ThrottlingParameter } from '../../../types/parameters'; +import type PickOptional from '../../../types/PickOptional'; interface ContextParameters { paymentId: string; - testmode?: boolean; } +export type CreateParameters = ContextParameters & PickOptional & IdempotencyParameter; + export type GetParameters = ContextParameters & { - embed?: CaptureEmbed[]; + include?: CaptureInclude; + testmode?: boolean; }; export type PageParameters = ContextParameters & PaginationParameters & { - embed?: CaptureEmbed[]; + include?: CaptureInclude; + testmode?: boolean; }; export type IterateParameters = Omit & ThrottlingParameter; diff --git a/src/binders/payments/parameters.ts b/src/binders/payments/parameters.ts index 54c4b029..bc674777 100644 --- a/src/binders/payments/parameters.ts +++ b/src/binders/payments/parameters.ts @@ -5,7 +5,7 @@ import { type IdempotencyParameter, type PaginationParameters, type ThrottlingPa import type PickOptional from '../../types/PickOptional'; export type CreateParameters = Pick & - PickOptional & { + PickOptional & { /** * Normally, a payment method screen is shown. However, when using this parameter, you can choose a specific payment method and your customer will skip the selection screen and is sent directly to * the chosen payment method. The parameter enables you to fully integrate the payment method selection into your website. diff --git a/src/createMollieClient.ts b/src/createMollieClient.ts index d6cf0e68..96c1debf 100644 --- a/src/createMollieClient.ts +++ b/src/createMollieClient.ts @@ -187,12 +187,12 @@ export default function createMollieClient(options: Options) { export { createMollieClient }; export { ApiMode, Locale, PaymentMethod, HistoricPaymentMethod, SequenceType } from './data/global'; -export { CaptureEmbed } from './data/payments/captures/data'; +export { CaptureInclude, CaptureStatus } from './data/payments/captures/data'; export { MandateMethod, MandateStatus } from './data/customers/mandates/data'; export { MethodImageSize, MethodInclude } from './data/methods/data'; export { OrderEmbed, OrderStatus } from './data/orders/data'; export { OrderLineType } from './data/orders/orderlines/OrderLine'; -export { PaymentEmbed, PaymentStatus } from './data/payments/data'; +export { PaymentEmbed, PaymentStatus, CaptureMethod } from './data/payments/data'; export { RefundEmbed, RefundStatus } from './data/refunds/data'; export { SubscriptionStatus } from './data/subscriptions/data'; export { ProfileStatus } from './data/profiles/data'; diff --git a/src/data/payments/captures/CaptureHelper.ts b/src/data/payments/captures/CaptureHelper.ts index dd8feafc..1fb594f4 100644 --- a/src/data/payments/captures/CaptureHelper.ts +++ b/src/data/payments/captures/CaptureHelper.ts @@ -12,6 +12,7 @@ import type Payment from '../Payment'; import { type PaymentData } from '../data'; import type Capture from './Capture'; import { type CaptureData } from './data'; +import type { Settlement, SettlementData } from '../../settlements/data'; export default class CaptureHelper extends Helper { constructor(networkClient: TransformingNetworkClient, protected readonly links: CaptureData['_links'], protected readonly embedded: Capture['_embedded']) { @@ -31,7 +32,7 @@ export default class CaptureHelper extends Helper { } /** - * Returns the shipment that triggered the capture to be created. + * Returns the shipment that triggered the capture to be created (if any). * * @since 3.6.0 */ @@ -41,4 +42,16 @@ export default class CaptureHelper extends Helper { if (renege(this, this.getShipment, ...arguments)) return; return runIf(this.links.shipment, ({ href }) => this.networkClient.get(href)) ?? undefinedPromise; } + + /** + * Returns the shipment this capture has been settled with (if any). + * + * @since 4.1.0 + */ + public getSettlement(): Promise | Promise; + public getSettlement(callback: Callback>): void; + public getSettlement() { + if (renege(this, this.getSettlement, ...arguments)) return; + return runIf(this.links.settlement, ({ href }) => this.networkClient.get(href)) ?? undefinedPromise; + } } diff --git a/src/data/payments/captures/data.ts b/src/data/payments/captures/data.ts index 9279f2cc..b8d881b5 100644 --- a/src/data/payments/captures/data.ts +++ b/src/data/payments/captures/data.ts @@ -1,6 +1,6 @@ import { type Amount, type ApiMode, type Links, type Url } from '../../global'; import type Model from '../../Model'; -import { type PaymentData } from '../data'; +import type { PaymentData } from '../data'; export interface CaptureData extends Model<'capture'> { /** @@ -11,6 +11,12 @@ export interface CaptureData extends Model<'capture'> { * @see https://docs.mollie.com/reference/v2/captures-api/get-capture?path=mode#response */ mode: ApiMode; + /** + * The description of the capture. + * + * @see https://docs.mollie.com/reference/v2/captures-api/get-capture?path=description#response + */ + description: string; /** * The amount captured. * @@ -18,11 +24,23 @@ export interface CaptureData extends Model<'capture'> { */ amount: Amount; /** - * This optional field will contain the amount that will be settled to your account, converted to the currency your account is settled in. It follows the same syntax as the `amount` property. + * This optional field will contain the approximate amount that will be settled to your account, converted to the currency your account is settled in. * * @see https://docs.mollie.com/reference/v2/captures-api/get-capture?path=settlementAmount#response */ settlementAmount: Amount; + /** + * The capture's status. + * + * @see https://docs.mollie.com/reference/v2/captures-api/get-capture?path=status#response + */ + status: CaptureStatus; + /** + * The capture's status. + * + * @see https://docs.mollie.com/reference/v2/captures-api/get-capture?path=metadata#response + */ + metadata: any; /** * The unique identifier of the payment this capture was created for, for example: `tr_7UhSN1zuXS`. The full payment object can be retrieved via the `payment` URL in the `_links` object. * @@ -30,14 +48,13 @@ export interface CaptureData extends Model<'capture'> { */ paymentId: string; /** - * The unique identifier of the shipment that triggered the creation of this capture, for example: `shp_3wmsgCJN4U`. The full shipment object can be retrieved via the `shipment` URL in the `_links` - * object. + * The unique identifier of the shipment that triggered the creation of this capture, if applicable. For example: `shp_3wmsgCJN4U`. * * @see https://docs.mollie.com/reference/v2/captures-api/get-capture?path=shipmentId#response */ shipmentId?: string; /** - * The unique identifier of the settlement this capture was settled with, for example: `stl_jDk30akdN`. The full settlement object can be retrieved via the `capture` URL in the `_links` object. + * The identifier referring to the settlement this capture was settled with. For example, `stl_BkEjN2eBb`. This field is omitted if the capture is not settled (yet). * * @see https://docs.mollie.com/reference/v2/captures-api/get-capture?path=settlementId#response */ @@ -59,11 +76,17 @@ export interface CaptureData extends Model<'capture'> { }; } -export enum CaptureEmbed { +export enum CaptureStatus { + pending = 'pending', + succeeded = 'succeeded', + failed = 'failed', +} + +export enum CaptureInclude { payment = 'payment', } -export interface CaptureLinks extends Links { +interface CaptureLinks extends Links { /** * The API resource URL of the payment the capture belongs to. * diff --git a/src/data/payments/data.ts b/src/data/payments/data.ts index 644896ec..39041ab3 100644 --- a/src/data/payments/data.ts +++ b/src/data/payments/data.ts @@ -162,6 +162,36 @@ export interface PaymentData extends Model<'payment'> { * @see https://docs.mollie.com/reference/v2/payments-api/get-payment?path=metadata#response */ metadata: unknown; + /** + * **Only relevant if you wish to manage authorization and capturing separately.** + * + * By default, the customer's card or bank account is immediately charged when they complete the payment. + * + * Some payment methods also allow placing a hold on the card or bank account. This hold or 'authorization' can then at a later point either be 'captured' or canceled. + * + * To enable this way of working, set the capture mode to `manual` and capture the payment manually using the `paymentCaptures.create` API. + */ + captureMode?: CaptureMethod; + /** + * **Only relevant if you wish to manage authorization and capturing separately.** + * + * Some payment methods allow placing a hold on the card or bank account. This hold or 'authorization' can then at a later point either be 'captured' or canceled. + * + * By default, we charge the customer's card or bank account immediately when they complete the payment. If you set a capture delay however, we will delay the automatic capturing of the payment for the specified amount of time. For example `8 hours` or `2 days`. + * + * To schedule an automatic capture, the `captureMode` must be set to `automatic`. + * + * The maximum delay is 7 days (168 hours). + * + * Possible values: `... hours`, `... days` + */ + captureDelay?: number; + /** + * **Only relevant if you wish to manage authorization and capturing separately.** + * + * Indicates the date before which the payment needs to be captured, in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. From this date onwards we can no longer guarantee a successful capture. The parameter is omitted if the payment is not authorized (yet). + */ + captureBefore?: number; /** * The customer's locale, either forced on creation by specifying the `locale` parameter, or detected by us during checkout. Will be a full locale, for example `nl_NL`. * @@ -868,6 +898,11 @@ export enum PaymentEmbed { captures = 'captures', } +export enum CaptureMethod { + automatic = 'automatic', + manual = 'manual', +} + export interface GiftCard { /** * The ID of the gift card brand that was used during the payment. diff --git a/src/data/settlements/data.ts b/src/data/settlements/data.ts index 96cb16eb..f119a0ce 100644 --- a/src/data/settlements/data.ts +++ b/src/data/settlements/data.ts @@ -1,6 +1,8 @@ import type Nullable from '../../types/Nullable'; +import type Seal from '../../types/Seal'; import { type Amount, type Links, type Url } from '../global'; import type Model from '../Model'; +import type SettlementHelper from './SettlementHelper'; export interface SettlementData extends Model<'settlement'> { /** @@ -54,6 +56,8 @@ export interface SettlementData extends Model<'settlement'> { _links: SettlementLinks; } +export type Settlement = Seal; + interface Period { /** * An array of revenue objects containing the total revenue for each payment method during this period. Each object has the following fields.