diff --git a/.release-please-manifest.json b/.release-please-manifest.json index c37434e..2969a75 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.110.0" + ".": "0.111.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 52a1884..ebb8318 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 240 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/increase%2Fincrease-c9957e6ab1c9adef0dfb9a3956c8e7505a1661d22e79531eaee71b2a3a699b61.yml -openapi_spec_hash: 1190741469af674747df81908239a601 -config_hash: 82cb0fb1fae47b3467cd6da4273541de +configured_endpoints: 241 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/increase%2Fincrease-ecd0cee565701f1d47c0db3efed2734f1195f60e5767c9c5f67ddb5de5e6abf1.yml +openapi_spec_hash: d9205bf9cc1ce52d0d046007318761a1 +config_hash: cb5b8736705c06b670f6a25484622d62 diff --git a/CHANGELOG.md b/CHANGELOG.md index f6e924e..77e221c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.111.0 (2026-04-13) + +Full Changelog: [v0.110.0...v0.111.0](https://github.com/Increase/increase-php/compare/v0.110.0...v0.111.0) + +### Features + +* **api:** api update ([20985e1](https://github.com/Increase/increase-php/commit/20985e1959f15994fa384a87e83c1d2892adba7f)) + ## 0.110.0 (2026-04-13) Full Changelog: [v0.109.0...v0.110.0](https://github.com/Increase/increase-php/compare/v0.109.0...v0.110.0) diff --git a/README.md b/README.md index 8f34e62..d12566c 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ The REST API documentation can be found on [increase.com](https://increase.com/d ``` -composer require "increase/increase 0.110.0" +composer require "increase/increase 0.111.0" ``` diff --git a/src/ServiceContracts/Simulations/CardPurchaseSupplementsContract.php b/src/ServiceContracts/Simulations/CardPurchaseSupplementsContract.php new file mode 100644 index 0000000..1980b6d --- /dev/null +++ b/src/ServiceContracts/Simulations/CardPurchaseSupplementsContract.php @@ -0,0 +1,36 @@ + $lineItems line item information, such as individual products purchased + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function create( + string $transactionID, + Invoice|array|null $invoice = null, + ?array $lineItems = null, + RequestOptions|array|null $requestOptions = null, + ): CardPurchaseSupplement; +} diff --git a/src/ServiceContracts/Simulations/CardPurchaseSupplementsRawContract.php b/src/ServiceContracts/Simulations/CardPurchaseSupplementsRawContract.php new file mode 100644 index 0000000..e0cd9c7 --- /dev/null +++ b/src/ServiceContracts/Simulations/CardPurchaseSupplementsRawContract.php @@ -0,0 +1,32 @@ +|CardPurchaseSupplementCreateParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function create( + array|CardPurchaseSupplementCreateParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; +} diff --git a/src/Services/Simulations/CardPurchaseSupplementsRawService.php b/src/Services/Simulations/CardPurchaseSupplementsRawService.php new file mode 100644 index 0000000..60a0def --- /dev/null +++ b/src/Services/Simulations/CardPurchaseSupplementsRawService.php @@ -0,0 +1,64 @@ +, + * }|CardPurchaseSupplementCreateParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function create( + array|CardPurchaseSupplementCreateParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = CardPurchaseSupplementCreateParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'simulations/card_purchase_supplements', + body: (object) $parsed, + options: $options, + convert: CardPurchaseSupplement::class, + ); + } +} diff --git a/src/Services/Simulations/CardPurchaseSupplementsService.php b/src/Services/Simulations/CardPurchaseSupplementsService.php new file mode 100644 index 0000000..b12c0c4 --- /dev/null +++ b/src/Services/Simulations/CardPurchaseSupplementsService.php @@ -0,0 +1,67 @@ +raw = new CardPurchaseSupplementsRawService($client); + } + + /** + * @api + * + * Simulates the creation of a Card Purchase Supplement (Level 3 data) for a card settlement. This happens asynchronously in production when Visa sends enhanced transaction data about a purchase. + * + * @param string $transactionID The identifier of the Transaction to create a Card Purchase Supplement for. The Transaction must have a source of type `card_settlement`. + * @param Invoice|InvoiceShape $invoice invoice-level information about the payment + * @param list $lineItems line item information, such as individual products purchased + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function create( + string $transactionID, + Invoice|array|null $invoice = null, + ?array $lineItems = null, + RequestOptions|array|null $requestOptions = null, + ): CardPurchaseSupplement { + $params = Util::removeNulls( + [ + 'transactionID' => $transactionID, + 'invoice' => $invoice, + 'lineItems' => $lineItems, + ], + ); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->create(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } +} diff --git a/src/Services/SimulationsService.php b/src/Services/SimulationsService.php index 6586446..7d4b1e2 100644 --- a/src/Services/SimulationsService.php +++ b/src/Services/SimulationsService.php @@ -15,6 +15,7 @@ use Increase\Services\Simulations\CardDisputesService; use Increase\Services\Simulations\CardFuelConfirmationsService; use Increase\Services\Simulations\CardIncrementsService; +use Increase\Services\Simulations\CardPurchaseSupplementsService; use Increase\Services\Simulations\CardRefundsService; use Increase\Services\Simulations\CardReversalsService; use Increase\Services\Simulations\CardSettlementsService; @@ -96,6 +97,11 @@ final class SimulationsService implements SimulationsContract */ public CardAuthenticationsService $cardAuthentications; + /** + * @api + */ + public CardPurchaseSupplementsService $cardPurchaseSupplements; + /** * @api */ @@ -222,6 +228,7 @@ public function __construct(private Client $client) $this->cardFuelConfirmations = new CardFuelConfirmationsService($client); $this->cardRefunds = new CardRefundsService($client); $this->cardAuthentications = new CardAuthenticationsService($client); + $this->cardPurchaseSupplements = new CardPurchaseSupplementsService($client); $this->cardDisputes = new CardDisputesService($client); $this->physicalCards = new PhysicalCardsService($client); $this->digitalWalletTokenRequests = new DigitalWalletTokenRequestsService($client); diff --git a/src/Simulations/CardPurchaseSupplements/CardPurchaseSupplementCreateParams.php b/src/Simulations/CardPurchaseSupplements/CardPurchaseSupplementCreateParams.php new file mode 100644 index 0000000..f56212b --- /dev/null +++ b/src/Simulations/CardPurchaseSupplements/CardPurchaseSupplementCreateParams.php @@ -0,0 +1,133 @@ +|null, + * } + */ +final class CardPurchaseSupplementCreateParams implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + use SdkParams; + + /** + * The identifier of the Transaction to create a Card Purchase Supplement for. The Transaction must have a source of type `card_settlement`. + */ + #[Required('transaction_id')] + public string $transactionID; + + /** + * Invoice-level information about the payment. + */ + #[Optional] + public ?Invoice $invoice; + + /** + * Line item information, such as individual products purchased. + * + * @var list|null $lineItems + */ + #[Optional('line_items', list: LineItem::class)] + public ?array $lineItems; + + /** + * `new CardPurchaseSupplementCreateParams()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * CardPurchaseSupplementCreateParams::with(transactionID: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new CardPurchaseSupplementCreateParams)->withTransactionID(...) + * ``` + */ + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + * + * @param Invoice|InvoiceShape|null $invoice + * @param list|null $lineItems + */ + public static function with( + string $transactionID, + Invoice|array|null $invoice = null, + ?array $lineItems = null, + ): self { + $self = new self; + + $self['transactionID'] = $transactionID; + + null !== $invoice && $self['invoice'] = $invoice; + null !== $lineItems && $self['lineItems'] = $lineItems; + + return $self; + } + + /** + * The identifier of the Transaction to create a Card Purchase Supplement for. The Transaction must have a source of type `card_settlement`. + */ + public function withTransactionID(string $transactionID): self + { + $self = clone $this; + $self['transactionID'] = $transactionID; + + return $self; + } + + /** + * Invoice-level information about the payment. + * + * @param Invoice|InvoiceShape $invoice + */ + public function withInvoice(Invoice|array $invoice): self + { + $self = clone $this; + $self['invoice'] = $invoice; + + return $self; + } + + /** + * Line item information, such as individual products purchased. + * + * @param list $lineItems + */ + public function withLineItems(array $lineItems): self + { + $self = clone $this; + $self['lineItems'] = $lineItems; + + return $self; + } +} diff --git a/src/Simulations/CardPurchaseSupplements/CardPurchaseSupplementCreateParams/Invoice.php b/src/Simulations/CardPurchaseSupplements/CardPurchaseSupplementCreateParams/Invoice.php new file mode 100644 index 0000000..1a4a1ad --- /dev/null +++ b/src/Simulations/CardPurchaseSupplements/CardPurchaseSupplementCreateParams/Invoice.php @@ -0,0 +1,243 @@ + */ + use SdkModel; + + /** + * Discount given to cardholder. + */ + #[Optional('discount_amount')] + public ?int $discountAmount; + + /** + * Amount of duty taxes. + */ + #[Optional('duty_tax_amount')] + public ?int $dutyTaxAmount; + + /** + * Date the order was taken. + */ + #[Optional('order_date')] + public ?string $orderDate; + + /** + * The shipping cost. + */ + #[Optional('shipping_amount')] + public ?int $shippingAmount; + + /** + * Country code of the shipping destination. + */ + #[Optional('shipping_destination_country_code')] + public ?string $shippingDestinationCountryCode; + + /** + * Postal code of the shipping destination. + */ + #[Optional('shipping_destination_postal_code')] + public ?string $shippingDestinationPostalCode; + + /** + * Postal code of the location being shipped from. + */ + #[Optional('shipping_source_postal_code')] + public ?string $shippingSourcePostalCode; + + /** + * Taxes paid for freight and shipping. + */ + #[Optional('shipping_tax_amount')] + public ?int $shippingTaxAmount; + + /** + * Tax rate for freight and shipping. + */ + #[Optional('shipping_tax_rate')] + public ?string $shippingTaxRate; + + /** + * Value added tax invoice reference number. + */ + #[Optional('unique_value_added_tax_invoice_reference')] + public ?string $uniqueValueAddedTaxInvoiceReference; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + */ + public static function with( + ?int $discountAmount = null, + ?int $dutyTaxAmount = null, + ?string $orderDate = null, + ?int $shippingAmount = null, + ?string $shippingDestinationCountryCode = null, + ?string $shippingDestinationPostalCode = null, + ?string $shippingSourcePostalCode = null, + ?int $shippingTaxAmount = null, + ?string $shippingTaxRate = null, + ?string $uniqueValueAddedTaxInvoiceReference = null, + ): self { + $self = new self; + + null !== $discountAmount && $self['discountAmount'] = $discountAmount; + null !== $dutyTaxAmount && $self['dutyTaxAmount'] = $dutyTaxAmount; + null !== $orderDate && $self['orderDate'] = $orderDate; + null !== $shippingAmount && $self['shippingAmount'] = $shippingAmount; + null !== $shippingDestinationCountryCode && $self['shippingDestinationCountryCode'] = $shippingDestinationCountryCode; + null !== $shippingDestinationPostalCode && $self['shippingDestinationPostalCode'] = $shippingDestinationPostalCode; + null !== $shippingSourcePostalCode && $self['shippingSourcePostalCode'] = $shippingSourcePostalCode; + null !== $shippingTaxAmount && $self['shippingTaxAmount'] = $shippingTaxAmount; + null !== $shippingTaxRate && $self['shippingTaxRate'] = $shippingTaxRate; + null !== $uniqueValueAddedTaxInvoiceReference && $self['uniqueValueAddedTaxInvoiceReference'] = $uniqueValueAddedTaxInvoiceReference; + + return $self; + } + + /** + * Discount given to cardholder. + */ + public function withDiscountAmount(int $discountAmount): self + { + $self = clone $this; + $self['discountAmount'] = $discountAmount; + + return $self; + } + + /** + * Amount of duty taxes. + */ + public function withDutyTaxAmount(int $dutyTaxAmount): self + { + $self = clone $this; + $self['dutyTaxAmount'] = $dutyTaxAmount; + + return $self; + } + + /** + * Date the order was taken. + */ + public function withOrderDate(string $orderDate): self + { + $self = clone $this; + $self['orderDate'] = $orderDate; + + return $self; + } + + /** + * The shipping cost. + */ + public function withShippingAmount(int $shippingAmount): self + { + $self = clone $this; + $self['shippingAmount'] = $shippingAmount; + + return $self; + } + + /** + * Country code of the shipping destination. + */ + public function withShippingDestinationCountryCode( + string $shippingDestinationCountryCode + ): self { + $self = clone $this; + $self['shippingDestinationCountryCode'] = $shippingDestinationCountryCode; + + return $self; + } + + /** + * Postal code of the shipping destination. + */ + public function withShippingDestinationPostalCode( + string $shippingDestinationPostalCode + ): self { + $self = clone $this; + $self['shippingDestinationPostalCode'] = $shippingDestinationPostalCode; + + return $self; + } + + /** + * Postal code of the location being shipped from. + */ + public function withShippingSourcePostalCode( + string $shippingSourcePostalCode + ): self { + $self = clone $this; + $self['shippingSourcePostalCode'] = $shippingSourcePostalCode; + + return $self; + } + + /** + * Taxes paid for freight and shipping. + */ + public function withShippingTaxAmount(int $shippingTaxAmount): self + { + $self = clone $this; + $self['shippingTaxAmount'] = $shippingTaxAmount; + + return $self; + } + + /** + * Tax rate for freight and shipping. + */ + public function withShippingTaxRate(string $shippingTaxRate): self + { + $self = clone $this; + $self['shippingTaxRate'] = $shippingTaxRate; + + return $self; + } + + /** + * Value added tax invoice reference number. + */ + public function withUniqueValueAddedTaxInvoiceReference( + string $uniqueValueAddedTaxInvoiceReference + ): self { + $self = clone $this; + $self['uniqueValueAddedTaxInvoiceReference'] = $uniqueValueAddedTaxInvoiceReference; + + return $self; + } +} diff --git a/src/Simulations/CardPurchaseSupplements/CardPurchaseSupplementCreateParams/LineItem.php b/src/Simulations/CardPurchaseSupplements/CardPurchaseSupplementCreateParams/LineItem.php new file mode 100644 index 0000000..f148a20 --- /dev/null +++ b/src/Simulations/CardPurchaseSupplements/CardPurchaseSupplementCreateParams/LineItem.php @@ -0,0 +1,237 @@ + */ + use SdkModel; + + /** + * Discount amount for this specific line item. + */ + #[Optional('discount_amount')] + public ?int $discountAmount; + + /** + * Code used to categorize the purchase item. + */ + #[Optional('item_commodity_code')] + public ?string $itemCommodityCode; + + /** + * Description of the purchase item. + */ + #[Optional('item_descriptor')] + public ?string $itemDescriptor; + + /** + * The number of units of the product being purchased. + */ + #[Optional('item_quantity')] + public ?string $itemQuantity; + + /** + * Code used to categorize the product being purchased. + */ + #[Optional('product_code')] + public ?string $productCode; + + /** + * Sales tax amount for this line item. + */ + #[Optional('sales_tax_amount')] + public ?int $salesTaxAmount; + + /** + * Sales tax rate for this line item. + */ + #[Optional('sales_tax_rate')] + public ?string $salesTaxRate; + + /** + * Total amount of all line items. + */ + #[Optional('total_amount')] + public ?int $totalAmount; + + /** + * Cost of line item per unit of measure, in major units. + */ + #[Optional('unit_cost')] + public ?string $unitCost; + + /** + * Code indicating unit of measure (gallons, etc.). + */ + #[Optional('unit_of_measure_code')] + public ?string $unitOfMeasureCode; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + */ + public static function with( + ?int $discountAmount = null, + ?string $itemCommodityCode = null, + ?string $itemDescriptor = null, + ?string $itemQuantity = null, + ?string $productCode = null, + ?int $salesTaxAmount = null, + ?string $salesTaxRate = null, + ?int $totalAmount = null, + ?string $unitCost = null, + ?string $unitOfMeasureCode = null, + ): self { + $self = new self; + + null !== $discountAmount && $self['discountAmount'] = $discountAmount; + null !== $itemCommodityCode && $self['itemCommodityCode'] = $itemCommodityCode; + null !== $itemDescriptor && $self['itemDescriptor'] = $itemDescriptor; + null !== $itemQuantity && $self['itemQuantity'] = $itemQuantity; + null !== $productCode && $self['productCode'] = $productCode; + null !== $salesTaxAmount && $self['salesTaxAmount'] = $salesTaxAmount; + null !== $salesTaxRate && $self['salesTaxRate'] = $salesTaxRate; + null !== $totalAmount && $self['totalAmount'] = $totalAmount; + null !== $unitCost && $self['unitCost'] = $unitCost; + null !== $unitOfMeasureCode && $self['unitOfMeasureCode'] = $unitOfMeasureCode; + + return $self; + } + + /** + * Discount amount for this specific line item. + */ + public function withDiscountAmount(int $discountAmount): self + { + $self = clone $this; + $self['discountAmount'] = $discountAmount; + + return $self; + } + + /** + * Code used to categorize the purchase item. + */ + public function withItemCommodityCode(string $itemCommodityCode): self + { + $self = clone $this; + $self['itemCommodityCode'] = $itemCommodityCode; + + return $self; + } + + /** + * Description of the purchase item. + */ + public function withItemDescriptor(string $itemDescriptor): self + { + $self = clone $this; + $self['itemDescriptor'] = $itemDescriptor; + + return $self; + } + + /** + * The number of units of the product being purchased. + */ + public function withItemQuantity(string $itemQuantity): self + { + $self = clone $this; + $self['itemQuantity'] = $itemQuantity; + + return $self; + } + + /** + * Code used to categorize the product being purchased. + */ + public function withProductCode(string $productCode): self + { + $self = clone $this; + $self['productCode'] = $productCode; + + return $self; + } + + /** + * Sales tax amount for this line item. + */ + public function withSalesTaxAmount(int $salesTaxAmount): self + { + $self = clone $this; + $self['salesTaxAmount'] = $salesTaxAmount; + + return $self; + } + + /** + * Sales tax rate for this line item. + */ + public function withSalesTaxRate(string $salesTaxRate): self + { + $self = clone $this; + $self['salesTaxRate'] = $salesTaxRate; + + return $self; + } + + /** + * Total amount of all line items. + */ + public function withTotalAmount(int $totalAmount): self + { + $self = clone $this; + $self['totalAmount'] = $totalAmount; + + return $self; + } + + /** + * Cost of line item per unit of measure, in major units. + */ + public function withUnitCost(string $unitCost): self + { + $self = clone $this; + $self['unitCost'] = $unitCost; + + return $self; + } + + /** + * Code indicating unit of measure (gallons, etc.). + */ + public function withUnitOfMeasureCode(string $unitOfMeasureCode): self + { + $self = clone $this; + $self['unitOfMeasureCode'] = $unitOfMeasureCode; + + return $self; + } +} diff --git a/src/Version.php b/src/Version.php index 0b584d5..e63c8d1 100644 --- a/src/Version.php +++ b/src/Version.php @@ -5,5 +5,5 @@ namespace Increase; // x-release-please-start-version -const VERSION = '0.110.0'; +const VERSION = '0.111.0'; // x-release-please-end diff --git a/tests/Services/Simulations/CardPurchaseSupplementsTest.php b/tests/Services/Simulations/CardPurchaseSupplementsTest.php new file mode 100644 index 0000000..fbcf36a --- /dev/null +++ b/tests/Services/Simulations/CardPurchaseSupplementsTest.php @@ -0,0 +1,77 @@ +client = $client; + } + + #[Test] + public function testCreate(): void + { + $result = $this->client->simulations->cardPurchaseSupplements->create( + transactionID: 'transaction_uyrp7fld2ium70oa7oi' + ); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(CardPurchaseSupplement::class, $result); + } + + #[Test] + public function testCreateWithOptionalParams(): void + { + $result = $this->client->simulations->cardPurchaseSupplements->create( + transactionID: 'transaction_uyrp7fld2ium70oa7oi', + invoice: [ + 'discountAmount' => 100, + 'dutyTaxAmount' => 200, + 'orderDate' => '2023-07-20', + 'shippingAmount' => 300, + 'shippingDestinationCountryCode' => 'US', + 'shippingDestinationPostalCode' => '10045', + 'shippingSourcePostalCode' => '10045', + 'shippingTaxAmount' => 400, + 'shippingTaxRate' => '0.2', + 'uniqueValueAddedTaxInvoiceReference' => '12302', + ], + lineItems: [ + [ + 'discountAmount' => 0, + 'itemCommodityCode' => '001', + 'itemDescriptor' => 'Coffee', + 'itemQuantity' => '1', + 'productCode' => '101', + 'salesTaxAmount' => 0, + 'salesTaxRate' => '-16699', + 'totalAmount' => 500, + 'unitCost' => '5', + 'unitOfMeasureCode' => 'NMB', + ], + ], + ); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(CardPurchaseSupplement::class, $result); + } +}