-
Notifications
You must be signed in to change notification settings - Fork 191
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
1,379 additions
and
270 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# HTTP Adapters | ||
|
||
## Overview | ||
|
||
An HTTP adapter is a component that manages the communication between your application and an API. It abstracts the details of making HTTP requests and handling responses, allowing you to use different HTTP clients (like Guzzle, cURL, or custom clients) interchangeably without changing the way you interact with the API. | ||
|
||
## MollieHttpAdapterPicker | ||
|
||
The `MollieHttpAdapterPicker` is responsible for selecting the appropriate HTTP adapter based on the environment or the provided HTTP client. If no client is specified in the `MollieApiClient` constructor, it picks a default adapter. | ||
|
||
### How It Works | ||
|
||
1. **No Client Specified**: If no client is provided, it checks if Guzzle is available and picks the appropriate version of the Guzzle adapter. | ||
2. **Custom Client Provided**: If a custom client is provided and it implements the `HttpAdapterContract`, it is used directly. If it's a Guzzle client, it is wrapped in a `GuzzleMollieHttpAdapter`. | ||
3. **Unrecognized Client**: Throws an `UnrecognizedClientException` if the client is not recognized. | ||
|
||
## Creating a Custom Adapter | ||
|
||
To create a custom HTTP adapter: | ||
1. Implement HttpAdapterContract. | ||
2. Use HasDefaultFactories Trait to simplify adapter implementation. | ||
|
||
```php | ||
use Mollie\Api\Contracts\HttpAdapterContract; | ||
use Mollie\Api\Traits\HasDefaultFactories; | ||
|
||
class MyCustomHttpAdapter implements HttpAdapterContract { | ||
use HasDefaultFactories; | ||
|
||
public function sendRequest(PendingRequest $pendingRequest): Response { | ||
// Implementation for sending HTTP request | ||
} | ||
|
||
public function version(): ?string { | ||
return 'my-custom-adapter/1.0'; | ||
} | ||
} | ||
``` | ||
|
||
### Debugging | ||
|
||
When debugging mode is enabled, adapters remove sensitive information before they fire an exception. | ||
|
||
Adapters that support debugging must implement the `SupportsDebuggingContract`. This contract defines methods `enableDebugging()` and `disableDebugging()` to control debugging behavior. | ||
|
||
```php | ||
use Mollie\Api\Contracts\SupportsDebuggingContract; | ||
|
||
class MyCustomHttpAdapter implements HttpAdapterContract, SupportsDebuggingContract { | ||
// Implementation of debugging methods | ||
} | ||
``` | ||
|
||
## Available Adapters | ||
|
||
Out of the box, the Mollie API client provides several adapters: | ||
|
||
- **GuzzleMollieHttpAdapter**: Wraps a Guzzle HTTP client for sending requests. | ||
- **CurlMollieHttpAdapter**: Uses cURL for sending HTTP requests. This is the default if Guzzle is not available. | ||
|
||
## Enabling Debugging | ||
|
||
Debugging can be enabled through the `HandlesDebugging` trait. This trait allows you to toggle debugging on the HTTP client, which is useful for development and troubleshooting. | ||
|
||
### How to Enable Debugging | ||
|
||
1. **Enable Debugging**: Call `enableDebugging()` on the Mollie API client instance. This sets the debugging mode on the underlying HTTP adapter, if it supports debugging. | ||
|
||
2. **Disable Debugging**: Call `disableDebugging()` to turn off debugging. | ||
|
||
```php | ||
$mollieClient->enableDebugging(); | ||
$mollieClient->disableDebugging(); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Idempotency | ||
|
||
## Overview | ||
|
||
Idempotency ensures that multiple identical requests to an API result in the same outcome without creating duplicate resources or effects. This is crucial for operations that involve financial transactions to prevent unintended charges or state changes. | ||
|
||
Mollie API supports idempotent requests for critical operations such as creating payments or refunds. This is automatically managed by the API client using the `ApplyIdempotencyKey` middleware. | ||
|
||
For more detailed information, refer to the [Mollie API Idempotency Documentation](https://docs.mollie.com/reference/api-idempotency). | ||
|
||
## Automatic Idempotency Key Handling | ||
|
||
The Mollie API client automatically handles idempotency for mutating requests (POST, PATCH, DELETE) through the `ApplyIdempotencyKey` middleware. This middleware checks if the request is a mutating type and applies an idempotency key if one is not already provided. | ||
|
||
### How It Works | ||
|
||
1. **Check Request Type**: The middleware checks if the request method is POST, PATCH, or DELETE. | ||
2. **Apply Idempotency Key**: If the request is mutating, the middleware will: | ||
- Use a custom idempotency key if provided. | ||
- Otherwise, generate a key using the configured `IdempotencyKeyGenerator` if available. | ||
- If no generator is set and no key is provided, no idempotency key is applied. | ||
|
||
### Customizing Idempotency Key | ||
|
||
You can customize how idempotency keys are generated or applied in several ways: | ||
|
||
- **Provide a Custom Key**: Manually set an idempotency key for a specific request. | ||
- **Use a Custom Generator**: Implement the `IdempotencyKeyGeneratorContract` to provide a custom method of generating idempotency keys. | ||
|
||
#### Example: Setting a Custom Key | ||
|
||
```php | ||
$mollie->setIdempotencyKey('your_custom_key_here'); | ||
``` | ||
|
||
#### Example: Using a Custom Key Generator | ||
|
||
Implement your key generator: | ||
|
||
```php | ||
class MyCustomKeyGenerator implements IdempotencyKeyGeneratorContract { | ||
public function generate(): string { | ||
return 'custom_' . bin2hex(random_bytes(10)); | ||
} | ||
} | ||
|
||
$mollie->setIdempotencyKeyGenerator(new MyCustomKeyGenerator()); | ||
``` | ||
|
||
## Best Practices | ||
|
||
- **Unique Keys**: Ensure that each idempotency key is unique to each operation. Typically, UUIDs are used for this purpose. | ||
- **Handling Errors**: Handle errors gracefully, especially when an API call with an idempotency key fails. Check the error message to understand whether you should retry the request with the same key or a new key. | ||
|
||
## Conclusionz | ||
|
||
Using idempotency keys in your API requests to Mollie can significantly enhance the reliability of your payment processing system, ensuring that payments are not unintentionally duplicated and that your application behaves predictably even in the face of network and service interruptions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
##### Multicurrency ##### | ||
Since API v2.0 it is now possible to create non-EUR payments for your customers. | ||
A full list of available currencies can be found [in our documentation](https://docs.mollie.com/guides/multicurrency). | ||
|
||
```php | ||
$payment = $mollie->payments->create([ | ||
"amount" => [ | ||
"currency" => "USD", | ||
"value" => "10.00" | ||
], | ||
//... | ||
]); | ||
``` | ||
_After creation, the `settlementAmount` will contain the EUR amount that will be settled on your account._ | ||
|
||
##### Create fully integrated iDEAL payments ##### | ||
To fully integrate iDEAL payments on your website, follow these additional steps: | ||
|
||
1. Retrieve the list of issuers (banks) that support iDEAL. | ||
|
||
```php | ||
$method = $mollie->methods->get(\Mollie\Api\Types\PaymentMethod::IDEAL, ["include" => "issuers"]); | ||
``` | ||
|
||
Use the `$method->issuers` list to let the customer pick their preferred issuer. | ||
|
||
_`$method->issuers` will be a list of objects. Use the property `$id` of this object in the | ||
API call, and the property `$name` for displaying the issuer to your customer._ | ||
|
||
2. Create a payment with the selected issuer: | ||
|
||
```php | ||
$payment = $mollie->payments->create([ | ||
"amount" => [ | ||
"currency" => "EUR", | ||
"value" => "10.00" | ||
], | ||
"description" => "My first API payment", | ||
"redirectUrl" => "https://webshop.example.org/order/12345/", | ||
"webhookUrl" => "https://webshop.example.org/mollie-webhook/", | ||
"method" => \Mollie\Api\Types\PaymentMethod::IDEAL, | ||
"issuer" => $selectedIssuerId, // e.g. "ideal_INGBNL2A" | ||
]); | ||
``` | ||
|
||
_The `_links` property of the `$payment` object will contain an object `checkout` with a `href` property, which is a URL that points directly to the online banking environment of the selected issuer. | ||
A short way of retrieving this URL can be achieved by using the `$payment->getCheckoutUrl()`._ | ||
|
||
For a more in-depth example, see [Example - iDEAL payment](https://github.com/mollie/mollie-api-php/blob/master/examples/payments/create-ideal-payment.php). | ||
|
||
#### Retrieving Payments #### | ||
**[Retrieve Payment Documentation](https://docs.mollie.com/reference/v2/payments-api/get-payment)** | ||
|
||
We can use the `$payment->id` to retrieve a payment and check if the payment `isPaid`. | ||
|
||
```php | ||
$payment = $mollie->payments->get($payment->id); | ||
|
||
if ($payment->isPaid()) | ||
{ | ||
echo "Payment received."; | ||
} | ||
``` | ||
|
||
Or retrieve a collection of payments. | ||
|
||
```php | ||
$payments = $mollie->payments->page(); | ||
``` | ||
|
||
For an extensive example of listing payments with the details and status, see [Example - List Payments](https://github.com/mollie/mollie-api-php/blob/master/examples/payments/list-payments.php). | ||
|
||
#### Refunding payments #### | ||
**[Refund Payment Documentation](https://docs.mollie.com/reference/v2/refunds-api/create-payment-refund)** | ||
|
||
Our API provides support for refunding payments. It's important to note that there is no confirmation step, and all refunds are immediate and final. Refunds are available for all payment methods except for paysafecard and gift cards. | ||
|
||
```php | ||
$payment = $mollie->payments->get($payment->id); | ||
|
||
// Refund € 2 of this payment | ||
$refund = $payment->refund([ | ||
"amount" => [ | ||
"currency" => "EUR", | ||
"value" => "2.00" | ||
] | ||
]); | ||
``` | ||
|
||
#### Payment webhook #### | ||
When the payment status changes, the `webhookUrl` you specified during payment creation will be called. You can use the `id` from the POST parameters to check the status and take appropriate actions. For more details, refer to [Example - Webhook](https://github.com/mollie/mollie-api-php/blob/master/examples/payments/webhook.php). | ||
|
||
For a working example, see [Example - Refund payment](https://github.com/mollie/mollie-api-php/blob/master/examples/payments/refund-payment.php). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Requests | ||
|
||
## Overview | ||
|
||
The Mollie API client uses request classes to communicate with the Mollie API. Each request class handles specific API endpoints and operations. | ||
|
||
## Sending a Request | ||
|
||
To send a request using the Mollie API client, you typically need to: | ||
|
||
1. **Create an instance of the client**: | ||
```php | ||
use Mollie\Api\MollieApiClient; | ||
|
||
$mollie = new MollieApiClient(); | ||
$mollie->setApiKey('test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM'); | ||
``` | ||
|
||
2. **Create and configure the request**: | ||
Depending on the operation, you might need to create an instance of a specific request class and configure it with necessary parameters. | ||
|
||
3. **Send the request**: | ||
Use the client to send the request and handle the response. | ||
```php | ||
use Mollie\Api\MollieApiClient; | ||
use Mollie\Api\Http\Payload\Money; | ||
use Mollie\Api\Http\Payload\CreatePaymentPayload; | ||
use Mollie\Api\Http\Requests\CreatePaymentRequest; | ||
|
||
$mollie = new MollieApiClient(); | ||
$createPaymentRequest = new CreatePaymentRequest( | ||
new CreatePaymentPayload( | ||
'Test payment', | ||
new Money('EUR', '10.00'), | ||
'https://example.org/redirect', | ||
'https://example.org/webhook' | ||
) | ||
); | ||
|
||
/** @var \Mollie\Api\Http\Response $response */ | ||
$response = $mollie->send($createPaymentRequest); | ||
|
||
$this->assertEquals(200, $response->status()); | ||
|
||
/** @var \Mollie\Api\Resources\Payment */ | ||
$payment = $response->toResource(); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# Responses | ||
|
||
Whether you interact with the endpoints using the traditional method (`$mollie->payments->...`) or the new `Request` classes, you can always inspect the `Response`. | ||
|
||
## Resource Hydration | ||
By default, the response from the `EndpointCollection`s automatically hydrates into the corresponding `Resource` or `ResourceCollection` objects. You can still access the raw response using the `->getResponse()` method. | ||
|
||
```php | ||
/** @var Mollie\Api\Resources\Payment $payment */ | ||
$payment = $mollie->payments->get('tr_*********'); | ||
|
||
$response = $payment->getResponse(); | ||
``` | ||
|
||
With the Request-based approach, you get a Response by default: | ||
|
||
```php | ||
/** @var Mollie\Api\Http\Response $response */ | ||
$response = $mollie->send(new GetPaymentRequest('tr_*********')); | ||
|
||
/** | ||
* Accessing the response is mainly for debugging, | ||
* like checking the status or inspecting the payload or URL. | ||
*/ | ||
$status = $response->status(); | ||
$sentPayload = $response->getPendingRequest()->payload; | ||
$sentUrlWithFilters = $response->getPendingRequest()->getUri(); | ||
|
||
/** @var Mollie\Api\Resources\Payment $payment */ | ||
$payment = $response->toResource(); | ||
``` | ||
|
||
Thanks to the DelegatesToResource Trait in Response, you can still access methods and attributes from the underlying Resource: | ||
|
||
```php | ||
// calling a method on the underlying Mollie\Api\Resources\Payment object | ||
$response->hasSplitPayments(); | ||
|
||
// accessing an attribute on the underlying Mollie\Api\Resources\Payment object | ||
$amount = $response->amount; | ||
``` | ||
|
||
If you prefer the old approach of directly receiving the Resource class, you can enable **auto-hydration** by calling `MollieApiClient::setAutoHydrate()`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Testing with Mollie API Client | ||
|
||
## Overview | ||
|
||
Version 3 of the Mollie API client refines the handling of the test mode parameter: | ||
|
||
- **Automatic Removal of Test Mode**: When using an API key, the test mode parameter is managed based on the key prefix (`test_` or `live_`). | ||
- **Explicit Test Mode Control**: For operations requiring explicit control, such as when using OAuth tokens, you can still pass the `testmode` parameter. | ||
|
||
## Enabling Test Mode | ||
|
||
### Global Test Mode | ||
|
||
You can enable test mode globally on the Mollie client. This setting will apply test mode to all operations performed with the client. | ||
|
||
```php | ||
use Mollie\Api\MollieApiClient; | ||
|
||
$mollie = new MollieApiClient(); | ||
$mollie->setApiKey("test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM"); | ||
$mollie->test(true); // Enable test mode globally | ||
``` | ||
|
||
### Per Request Test Mode | ||
|
||
For specific control, you can enable test mode per request. This is useful for mixed-mode operations. | ||
|
||
```php | ||
// Creating a payment in test mode | ||
use Mollie\Api\MollieApiClient; | ||
use Mollie\Api\Http\Payload\Money; | ||
use Mollie\Api\Http\Payload\CreatePaymentPayload; | ||
use Mollie\Api\Http\Requests\CreatePaymentRequest; | ||
|
||
$mollie = new MollieApiClient(); | ||
$createPaymentRequest = new CreatePaymentRequest( | ||
new CreatePaymentPayload( | ||
'Test payment', | ||
new Money('EUR', '10.00'), | ||
'https://example.org/redirect', | ||
'https://example.org/webhook' | ||
) | ||
); | ||
|
||
$mollie->send($createPaymentRequest->test(true)); | ||
``` | ||
|
||
### Using Test Mode with Endpoint Collections | ||
|
||
When using endpoint collections, pass the test mode parameter directly to methods that support it. | ||
|
||
```php | ||
// Fetch a customer in test mode | ||
$customer = $mollie->customers->get('cust_12345678', testmode: true); | ||
``` |
Oops, something went wrong.