Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@ All notable changes to `vatly-api-php` will be documented in this file.

- **`Order->cancellationReason`**: nullable string explaining why an order was canceled. `payment_failure` when payment recovery for the unpaid order was exhausted, otherwise `null`. Always `null` unless the order's `status` is `canceled`, and `null` for orders canceled before the API exposed this field. Compare against `Vatly\API\Types\CancellationReason::PAYMENT_FAILURE`.
- **`cancellationReason` on the `OrderCanceled` webhook DTO**: a nullable `?string`, read straight from the delivery's `object`. Additive: it is an optional constructor argument that defaults to `null`.
- **`orderId` on the refund webhook DTOs**: `RefundCompleted`, `RefundFailed`, and `RefundCanceled` now expose `orderId` (`?string`): the credit order Vatly creates from a refund, whose `customerInvoice` is the credit note. It is hydrated from the signed refund payload like every other field (the id is already present there), so a consumer stamping the credit note can reach it with a single `GetOrder` instead of first re-fetching the refund with `GetRefund`. `null` until a credit order has materialized.

### Fixed

- **`orderRefunds->createFullRefundForOrderId()` no longer changes the path of later calls.** It left `/full` on the shared endpoint, so every later `orderRefunds` call on the same client went to the wrong URL: a partial refund was sent to `/orders/{id}/refunds/full`, and a second full refund to `/refunds/full/full`. `Order::fullRefund()` was affected too. Long-lived clients, such as queue workers, are the ones that could hit this.
- **`subscriptions->listForCustomerId()` and `listForCustomer()` now return only that customer's subscriptions.** They called `GET /subscriptions` with a `customer_id` parameter the API does not support, so the response held every subscription for the API token's storefront and mode. They now call `GET /customers/{customerId}/subscriptions`. If you worked around this by filtering the result yourself, that filter is no longer needed.
- `docs/Orders.md` now matches the Order resource and the API: the statuses are `created`, `pending`, `paid`, `canceled` and `expired`, the helpers are `isCreated()`, `isPaid()`, `isPending()`, `isCanceled()` and `isExpired()` plus the reversal helpers (there is no `failed` status or `isFailed()`), and the properties and examples use the real fields (`total` and `subtotal` as `Money`, no `amount`, `currency`, `taxAmount`, `paidAt`, `checkoutId` or `subscriptionId`).
- Corrected the code samples and reference tables in `docs/`, which called methods the SDK does not have:
- The list samples for checkouts, customers, subscriptions, refunds and chargebacks now call `page()`. There is no `list()` method, and `limit` and `startingAfter` are positional arguments, not an array. `endingBefore` is documented too.
- `docs/Refunds.md` now uses `orderRefunds->createForOrderId()` and `createFullRefundForOrderId()` (there is no `refunds->create()`), the `items` request body, the real properties and statuses, and documents canceling a refund. The status helpers it listed do not exist.
- The hosted checkout URL is read from `$checkout->links->checkoutUrl->href`. `getCheckoutUrl()` and `getOrderId()` do not exist.
- Removed the `customerId` filter on the subscriptions list, which the API does not offer, in favor of `customerSubscriptions->pageForCustomerId()`.
- `docs/Checkouts.md` and `docs/Chargebacks.md` no longer list `merchantId`, and the properties tables now include the fields the API returns. `docs/Chargebacks.md` also lists the dispute statuses.

## v0.1.0-alpha.30

Expand Down
35 changes: 29 additions & 6 deletions docs/Chargebacks.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@ Below you'll find all properties for the Vatly Chargeback resource.
| --- | --- | --- |
| `id` | `string` | Unique identifier for the chargeback (`chargeback_...`). |
| `resource` | `string` | Always `chargeback`. |
| `merchantId` | `string` | The merchant ID. |
| `customerId` | `string` | ID of the customer who disputed the payment. |
| `testmode` | `bool` | Whether this is a test chargeback. |
| `amount` | `object` | Chargeback amount (`value` and `currency`). |
| `settlementAmount` | `object` | Amount deducted from settlement (may differ from `amount`). |
| `status` | `string` | The dispute status (see [Chargeback statuses](#chargeback-statuses)). |
| `amount` | `Money` | Amount of the chargeback. |
| `settlementAmount` | `Money` | Amount deducted from settlement (may differ from `amount` due to currency conversion or fees). |
| `total` | `Money` | Total amount including taxes. |
| `subtotal` | `Money` | Subtotal amount before taxes. |
| `taxSummary` | `TaxSummaryCollection` | Tax breakdown by rate. |
| `reason` | `string` | Reason code for the dispute (e.g. `fraud`, `product_not_received`, `duplicate`). |
| `originalOrderId` | `string` | The ID of the original order that was disputed. |
| `orderId` | `string \| null` | The credit note order ID (after processing). |
| `orderId` | `string \| null` | The credit note order ID, `null` until the chargeback is processed. |
| `createdAt` | `string` | Creation timestamp (ISO 8601). |
| `links` | `ChargebackLinks` | Links to this chargeback, the original order and the credit note order (`null` until there is one). |

---

Expand Down Expand Up @@ -58,16 +63,34 @@ Retrieve a paginated list of all chargebacks.

| Name | Type | Description |
| --- | --- | --- |
| `startingAfter` | `string` | A cursor for pagination: return the page after this chargeback ID. |
| `endingBefore` | `string` | A cursor for pagination: return the page before this chargeback ID. |
| `limit` | `integer` | The number of chargebacks to return (default: 10, max: 100). |
| `startingAfter` | `string` | A cursor for pagination. |




```php
$chargebacks = $vatly->chargebacks->list();
$chargebacks = $vatly->chargebacks->page();

foreach ($chargebacks as $chargeback) {
echo $chargeback->id . ': ' . $chargeback->reason;
}

// Pass the cursors and limit in order: startingAfter, endingBefore, limit
$chargebacks = $vatly->chargebacks->page('chargeback_last_id', null, 25);
```

---

## Chargeback statuses

| Status | Description |
|--------|-------------|
| `pending` | Dispute received, awaiting action |
| `requires_amount_review` | The disputed amount exceeds the original order, so completion is held pending review |
| `accepted` | The dispute was accepted |
| `rejected` | The dispute was rejected |
| `evidence_submitted` | Evidence submitted, awaiting a decision |
| `won` | Dispute resolved in the merchant's favor |
| `lost` | Dispute resolved in the customer's favor |
30 changes: 15 additions & 15 deletions docs/Checkouts.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ Below you'll find all properties for the Vatly Checkout resource.
| Name | Type | Description |
| --- | --- | --- |
| `id` | `string` | Unique identifier for the checkout (`checkout_...`). |
| `resource` | `string` | Always `checkout`. |
| `status` | `string` | The status of the checkout: `created`, `paid`, `canceled`, `failed`, or `expired`. |
| `merchantId` | `string` | Your merchant ID. |
| `customerId` | `string \| null` | The customer ID, or `null` when the checkout has no associated customer yet. |
| `orderId` | `string \| null` | Order ID (available after successful payment). |
| `testmode` | `bool` | Whether this is a test checkout. |
| `redirectUrlSuccess` | `string` | Success redirect URL. |
Expand All @@ -23,6 +24,7 @@ Below you'll find all properties for the Vatly Checkout resource.
| `locale` | `string \| null` | The language the hosted checkout is presented in (`en`, `de`, `fr`, `nl`, `es`, `it`, `pt`, `pl`), echoed back as the folded language. `null` means none was specified and the checkout picks a language from the shopper's browser. |
| `expiresAt` | `string \| null` | Expiration timestamp (ISO 8601). |
| `createdAt` | `string` | Creation timestamp (ISO 8601). |
| `links` | `CheckoutLinks` | Links to this checkout, the hosted checkout page (`checkoutUrl`) and the order (`null` until there is one). |

---

Expand Down Expand Up @@ -74,7 +76,7 @@ $checkout = $vatly->checkouts->create([
echo $checkout->locale; // 'de'

// Redirect to hosted checkout
$checkoutUrl = $checkout->getCheckoutUrl();
$checkoutUrl = $checkout->links->checkoutUrl->href;
```

If you want to provide your own idempotency key for this request, pass it in the optional second argument:
Expand Down Expand Up @@ -157,7 +159,7 @@ $checkout = $vatly->checkouts->get('checkout_abc123');

echo $checkout->id;
echo $checkout->status;
echo $checkout->getCheckoutUrl();
echo $checkout->links->checkoutUrl->href;

if ($checkout->isPaid()) {
$orderId = $checkout->orderId;
Expand All @@ -180,25 +182,23 @@ Retrieve a paginated list of all your checkouts.

| Name | Type | Description |
| --- | --- | --- |
| `startingAfter` | `string` | A cursor for pagination: return the page after this checkout ID. |
| `endingBefore` | `string` | A cursor for pagination: return the page before this checkout ID. |
| `limit` | `integer` | The number of checkouts to return (default: 10, max: 100). |
| `startingAfter` | `string` | A cursor for pagination. Returns results after this checkout ID. |




```php
// Get all checkouts (paginated)
$checkouts = $vatly->checkouts->list();
$checkouts = $vatly->checkouts->page();

foreach ($checkouts as $checkout) {
echo $checkout->id . ': ' . $checkout->status;
}

// Pagination
$checkouts = $vatly->checkouts->list([
'limit' => 25,
'startingAfter' => 'checkout_last_id',
]);
// Pass the cursors and limit in order: startingAfter, endingBefore, limit
$checkouts = $vatly->checkouts->page('checkout_last_id', null, 25);
```


Expand Down Expand Up @@ -227,9 +227,9 @@ The Checkout object provides convenient helper methods.


```php
$checkout->isPaid(); // true if status is 'paid'
$checkout->isCanceled(); // true if status is 'canceled'
$checkout->isExpired(); // true if status is 'expired'
$checkout->getCheckoutUrl(); // Hosted checkout page URL
$checkout->getOrderId(); // Order ID (null if not paid)
$checkout->isCreated(); // true if status is 'created'
$checkout->isPaid(); // true if status is 'paid'
$checkout->isCanceled(); // true if status is 'canceled'
$checkout->isFailed(); // true if status is 'failed'
$checkout->isExpired(); // true if status is 'expired'
```
14 changes: 7 additions & 7 deletions docs/Customers.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ Below you'll find all properties for the Vatly Customer resource.
| Name | Type | Description |
| --- | --- | --- |
| `id` | `string` | Unique identifier for the customer (`customer_...`). |
| `resource` | `string` | Always `customer`. |
| `email` | `string` | Customer's email address. |
| `name` | `string \| null` | Customer's name. |
| `testmode` | `bool` | Whether this is a test customer. |
| `metadata` | `array` | Your custom metadata. |
| `createdAt` | `string` | Creation timestamp (ISO 8601). |
| `links` | `CustomerLinks` | Link to this customer. |

---

Expand Down Expand Up @@ -138,24 +140,22 @@ Retrieve a paginated list of all your customers.

| Name | Type | Description |
| --- | --- | --- |
| `startingAfter` | `string` | A cursor for pagination: return the page after this customer ID. |
| `endingBefore` | `string` | A cursor for pagination: return the page before this customer ID. |
| `limit` | `integer` | The number of customers to return (default: 10, max: 100). |
| `startingAfter` | `string` | A cursor for pagination. Returns results after this customer ID. |




```php
$customers = $vatly->customers->list();
$customers = $vatly->customers->page();

foreach ($customers as $customer) {
echo $customer->email;
}

// Pagination
$customers = $vatly->customers->list([
'limit' => 25,
'startingAfter' => 'customer_last_id',
]);
// Pass the cursors and limit in order: startingAfter, endingBefore, limit
$customers = $vatly->customers->page('customer_last_id', null, 25);
```

---
Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ $checkout = $vatly->checkouts->create([
]);

// Redirect customer to checkout
header('Location: ' . $checkout->getCheckoutUrl());
header('Location: ' . $checkout->links->checkoutUrl->href);
```


Expand Down
Loading
Loading