├── .github ├── FUNDING.yml └── workflows │ └── run-tests.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── composer.json ├── phpunit.xml.dist ├── src ├── Gateway.php ├── Item.php └── Message │ ├── Request │ ├── AbstractMollieRequest.php │ ├── CancelOrderRequest.php │ ├── CompleteOrderRequest.php │ ├── CompletePurchaseRequest.php │ ├── CreateCustomerMandateRequest.php │ ├── CreateCustomerRequest.php │ ├── CreateOrderRequest.php │ ├── CreateShipmentRequest.php │ ├── FetchCustomerMandatesRequest.php │ ├── FetchCustomerRequest.php │ ├── FetchIssuersRequest.php │ ├── FetchOrderRequest.php │ ├── FetchPaymentMethodsRequest.php │ ├── FetchTransactionRequest.php │ ├── PurchaseRequest.php │ ├── RefundRequest.php │ ├── RevokeCustomerMandateRequest.php │ └── UpdateCustomerRequest.php │ └── Response │ ├── AbstractMollieResponse.php │ ├── CancelOrderResponse.php │ ├── CompleteOrderResponse.php │ ├── CompletePurchaseResponse.php │ ├── CreateCustomerMandateResponse.php │ ├── CreateCustomerResponse.php │ ├── CreateOrderResponse.php │ ├── CreateShipmentResponse.php │ ├── FetchCustomerMandatesResponse.php │ ├── FetchCustomerResponse.php │ ├── FetchIssuersResponse.php │ ├── FetchOrderResponse.php │ ├── FetchPaymentMethodsResponse.php │ ├── FetchTransactionResponse.php │ ├── PurchaseResponse.php │ ├── RefundResponse.php │ ├── RevokeCustomerMandateResponse.php │ └── UpdateCustomerResponse.php └── tests ├── GatewayTest.php ├── Message ├── AbstractMollieRequestTest.php ├── AssertRequestTrait.php ├── CancelOrderRequestTest.php ├── CompleteOrderRequestTest.php ├── CompletePurchaseRequestTest.php ├── CreateCustomerMandateRequestTest.php ├── CreateCustomerRequestTest.php ├── CreateOrderRequestTest.php ├── CreateShipmentRequestTest.php ├── FetchCustomerMandatesRequestTest.php ├── FetchCustomerRequestTest.php ├── FetchIssuersRequestTest.php ├── FetchOrderRequestTest.php ├── FetchPaymentMethodsRequestTest.php ├── FetchTransactionRequestTest.php ├── PurchaseRequestTest.php ├── RefundRequestTest.php ├── RevokeCustomerMandateRequestTest.php └── UpdateCustomerRequestTest.php └── Mock ├── CompleteOrderSuccess.txt ├── CompletePurchaseExpired.txt ├── CompletePurchaseSuccess.txt ├── CreateCustomerFailure.txt ├── CreateCustomerMandateFailure.txt ├── CreateCustomerMandateSuccess.txt ├── CreateCustomerSuccess.txt ├── CreateOrderFailure.txt ├── CreateOrderRequest.txt ├── CreateOrderSuccess.txt ├── CreateShipmentSuccess.txt ├── FetchCustomerFailure.txt ├── FetchCustomerMandatesFailure.txt ├── FetchCustomerMandatesSuccess.txt ├── FetchCustomerSuccess.txt ├── FetchIssuersFailure.txt ├── FetchIssuersSuccess.txt ├── FetchOrderSuccess.txt ├── FetchPaymentMethodsFailure.txt ├── FetchPaymentMethodsSuccess.txt ├── FetchTransaction404Failure.txt ├── FetchTransactionExpired.txt ├── FetchTransactionSuccess.txt ├── PurchaseIssuerFailure.txt ├── PurchaseSuccess.txt ├── Refund401Failure.txt ├── Refund422Failure.txt ├── RefundSuccess.txt ├── RevokeCustomerMandateSuccess.txt ├── UpdateCustomerFailure.txt └── UpdateCustomerSuccess.txt /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [barryvdh] -------------------------------------------------------------------------------- /.github/workflows/run-tests.yml: -------------------------------------------------------------------------------- 1 | name: Unit Tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - "*" 10 | schedule: 11 | - cron: '0 0 * * *' 12 | 13 | jobs: 14 | php-tests: 15 | runs-on: ubuntu-latest 16 | timeout-minutes: 15 17 | env: 18 | COMPOSER_NO_INTERACTION: 1 19 | 20 | strategy: 21 | matrix: 22 | php: [8.0, 7.4, 7.3, 7.2] 23 | dependency-version: [prefer-lowest, prefer-stable] 24 | 25 | name: P${{ matrix.php }} - ${{ matrix.dependency-version }} 26 | 27 | steps: 28 | - name: Checkout code 29 | uses: actions/checkout@v2 30 | 31 | - name: Setup PHP 32 | uses: shivammathur/setup-php@v2 33 | with: 34 | php-version: ${{ matrix.php }} 35 | coverage: none 36 | tools: composer:v2 37 | 38 | - name: Install dependencies 39 | run: | 40 | composer update --${{ matrix.dependency-version }} --prefer-dist --no-progress 41 | 42 | - name: Execute Unit Tests 43 | run: composer test 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | composer.lock 3 | composer.phar 4 | phpunit.xml 5 | /.idea 6 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | * Fork the project. 4 | * Make your feature addition or bug fix. 5 | * Add tests for it. This is important so I don't break it in a future version unintentionally. 6 | * Commit just the modifications, do not mess with the composer.json or CHANGELOG.md files. 7 | * Ensure your code is nicely formatted in the [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) 8 | style and that all tests pass. 9 | * Send the pull request. 10 | * Check that the Travis CI build passed. If not, rinse and repeat. 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2013 Adrian Macneil 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Omnipay: Mollie 2 | 3 | **Mollie driver for the Omnipay PHP payment processing library** 4 | 5 | [![Unit Tests](https://github.com/thephpleague/omnipay-mollie/actions/workflows/run-tests.yml/badge.svg)](https://github.com/thephpleague/omnipay-mollie/actions/workflows/run-tests.yml) 6 | [![Latest Stable Version](https://poser.pugx.org/omnipay/mollie/version.png)](https://packagist.org/packages/omnipay/mollie) 7 | [![Total Downloads](https://poser.pugx.org/omnipay/mollie/d/total.png)](https://packagist.org/packages/omnipay/mollie) 8 | 9 | [Omnipay](https://github.com/thephpleague/omnipay) is a framework agnostic, multi-gateway payment 10 | processing library for PHP. This package implements Mollie support for Omnipay. 11 | 12 | ## Installation 13 | 14 | Omnipay is installed via [Composer](http://getcomposer.org/). To install, simply require `league/omnipay` and `omnipay/mollie` with Composer: 15 | 16 | ``` 17 | composer require league/omnipay omnipay/mollie 18 | ``` 19 | 20 | 21 | ## Basic Usage 22 | 23 | The following gateways are provided by this package: 24 | 25 | * Mollie 26 | 27 | For general usage instructions, please see the main [Omnipay](https://github.com/thephpleague/omnipay) 28 | repository. 29 | 30 | ### Basic purchase example 31 | 32 | ```php 33 | $gateway = \Omnipay\Omnipay::create('Mollie'); 34 | $gateway->setApiKey('test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM'); 35 | 36 | $response = $gateway->purchase( 37 | [ 38 | "amount" => "10.00", 39 | "currency" => "EUR", 40 | "description" => "My first Payment", 41 | "returnUrl" => "https://webshop.example.org/mollie-return.php" 42 | ] 43 | )->send(); 44 | 45 | // Process response 46 | if ($response->isSuccessful()) { 47 | 48 | // Payment was successful 49 | print_r($response); 50 | 51 | } elseif ($response->isRedirect()) { 52 | 53 | // Redirect to offsite payment gateway 54 | $response->redirect(); 55 | 56 | } else { 57 | 58 | // Payment failed 59 | echo $response->getMessage(); 60 | } 61 | ``` 62 | 63 | ### Example using the Order API 64 | 65 | 1. Create the order and pass the order items in the parameters. 66 | 67 | ```php 68 | $response = $gateway->createOrder( 69 | [ 70 | 'amount' => '1027.99', 71 | 'currency' => 'EUR', 72 | 'orderNumber' => '1337', 73 | 'lines' => [ 74 | [ 75 | 'type' => 'physical', 76 | 'sku' => '5702016116977', 77 | 'name' => 'LEGO 42083 Bugatti Chiron', 78 | 'productUrl' => 'https://shop.lego.com/nl-NL/Bugatti-Chiron-42083', 79 | 'imageUrl' => 'https://sh-s7-live-s.legocdn.com/is/image//LEGO/42083_alt1?$main$', 80 | 'quantity' => 2, 81 | 'vatRate' => '21.00', 82 | 'unitPrice' => '399.00', 83 | 'totalAmount' => '698.00', 84 | 'discountAmount' => '100.00', 85 | 'vatAmount' => '121.14', 86 | ], 87 | [ 88 | 'type' => 'physical', 89 | 'sku' => '5702015594028', 90 | 'name' => 'LEGO 42056 Porsche 911 GT3 RS', 91 | 'productUrl' => 'https://shop.lego.com/nl-NL/Porsche-911-GT3-RS-42056', 92 | 'imageUrl' => 'https://sh-s7-live-s.legocdn.com/is/image/LEGO/42056?$PDPDefault$', 93 | 'quantity' => 1, 94 | 'vatRate' => '21.00', 95 | 'unitPrice' => '329.99', 96 | 'totalAmount' => '329.99', 97 | 'vatAmount' => '57.27', 98 | ] 99 | ], 100 | 'card' => [ 101 | 'company' => 'Mollie B.V.', 102 | 'email' => 'norris@chucknorrisfacts.net', 103 | 'birthday' => '1958-01-31', 104 | 'billingTitle' => 'Dhr', 105 | 'billingFirstName' => 'Piet', 106 | 'billingLastName' => 'Mondriaan', 107 | 'billingAddress1' => 'Keizersgracht 313', 108 | 'billingCity' => 'Amsterdam', 109 | 'billingPostcode' => '1234AB', 110 | 'billingState' => 'Noord-Holland', 111 | 'billingCountry' => 'NL', 112 | 'billingPhone' => '+31208202070', 113 | 'shippingTitle' => 'Mr', 114 | 'shippingFirstName' => 'Chuck', 115 | 'shippingLastName' => 'Norris', 116 | 'shippingAddress1' => 'Prinsengracht 313', 117 | 'shippingAddress2' => '4th floor', 118 | 'shippingCity' => 'Haarlem', 119 | 'shippingPostcode' => '5678AB', 120 | 'shippingState' => 'Noord-Holland', 121 | 'shippingCountry' => 'NL', 122 | ], 123 | 'metadata' => [ 124 | 'order_id' => '1337', 125 | 'description' => 'Lego cars', 126 | ], 127 | 'locale' => 'nl_NL', 128 | 'returnUrl' => 'https://example.org/redirect', 129 | 'notifyUrl' => 'https://example.org/webhook', 130 | 'paymentMethod' => 'klarnapaylater', 131 | 'billingEmail' => 'piet@mondriaan.com', 132 | ] 133 | )->send(); 134 | 135 | // Process response 136 | if ($response->isSuccessful()) { 137 | 138 | // Payment was successful 139 | print_r($response); 140 | 141 | } elseif ($response->isRedirect()) { 142 | 143 | // Redirect to offsite payment gateway 144 | $response->redirect(); 145 | 146 | } else { 147 | 148 | // Payment failed 149 | echo $response->getMessage(); 150 | } 151 | ``` 152 | 153 | 2. On return/notify, complete the order. This will not always be completed, because for Klarna the shipments needs to be created first. 154 | 155 | 156 | ```php 157 | $response = $gateway->completeOrder( 158 | [ 159 | "transactionReference" => "ord_xxxx", 160 | ] 161 | )->send(); 162 | ``` 163 | 164 | 3. When shipping the items, create the shipment for this order. You can leave the `items` emtpy to ship all items. 165 | 166 | ```php 167 | $response = $gateway->createShipment( 168 | [ 169 | "transactionReference" => "ord_xxx", 170 | 'items' => [ 171 | [ 172 | 'id' => 'odl_xxx', 173 | 'quantity' => 1, 174 | ] 175 | ] 176 | ] 177 | )->send(); 178 | ``` 179 | 180 | 4. As long as the order is `created`, `authorized` or `shipping`, it may be cancelled (voided) 181 | 182 | ```php 183 | $response = $gateway->void(["transactionReference" => "ord_xxx"])->send(); 184 | ``` 185 | 186 | ## Support 187 | 188 | If you are having general issues with Omnipay, we suggest posting on 189 | [Stack Overflow](http://stackoverflow.com/). Be sure to add the 190 | [omnipay tag](http://stackoverflow.com/questions/tagged/omnipay) so it can be easily found. 191 | 192 | If you want to keep up to date with release announcements, discuss ideas for the project, 193 | or ask more detailed questions, there is also a [mailing list](https://groups.google.com/forum/#!forum/omnipay) which 194 | you can subscribe to. 195 | 196 | If you believe you have found a bug, please report it using the [GitHub issue tracker](https://github.com/thephpleague/omnipay-mollie/issues), 197 | or better yet, fork the library and submit a pull request. 198 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "omnipay/mollie", 3 | "type": "library", 4 | "description": "Mollie driver for the Omnipay payment processing library", 5 | "keywords": [ 6 | "gateway", 7 | "merchant", 8 | "mollie", 9 | "omnipay", 10 | "pay", 11 | "payment" 12 | ], 13 | "homepage": "https://github.com/thephpleague/omnipay-mollie", 14 | "license": "MIT", 15 | "authors": [ 16 | { 17 | "name": "Adrian Macneil", 18 | "email": "adrian@adrianmacneil.com" 19 | }, 20 | { 21 | "name": "Barry vd. Heuvel", 22 | "email": "barryvdh@gmail.com" 23 | }, 24 | { 25 | "name": "Omnipay Contributors", 26 | "homepage": "https://github.com/thephpleague/omnipay-mollie/contributors" 27 | } 28 | ], 29 | "autoload": { 30 | "psr-4": { "Omnipay\\Mollie\\" : "src/" } 31 | }, 32 | "autoload-dev": { 33 | "psr-4": { "Omnipay\\Mollie\\Test\\": "tests/" } 34 | }, 35 | "require": { 36 | "php": "^7.2|^8.0", 37 | "omnipay/common": "^3.1" 38 | }, 39 | "require-dev": { 40 | "omnipay/tests": "^4.1", 41 | "squizlabs/php_codesniffer": "^3" 42 | }, 43 | "extra": { 44 | "branch-alias": { 45 | "dev-master": "5.5.x-dev" 46 | } 47 | }, 48 | "scripts": { 49 | "test": "phpunit", 50 | "check-style": "phpcs -p --standard=PSR2 src/", 51 | "fix-style": "phpcbf -p --standard=PSR2 src/" 52 | }, 53 | "prefer-stable": true 54 | } 55 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./src 16 | 17 | 18 | 19 | 20 | ./tests/ 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Gateway.php: -------------------------------------------------------------------------------- 1 | '', 63 | ); 64 | } 65 | 66 | /** 67 | * @return string 68 | */ 69 | public function getApiKey() 70 | { 71 | return $this->getParameter('apiKey'); 72 | } 73 | 74 | /** 75 | * @param string $value 76 | * @return $this 77 | */ 78 | public function setApiKey($value) 79 | { 80 | return $this->setParameter('apiKey', $value); 81 | } 82 | 83 | /** 84 | * @return array|null 85 | */ 86 | public function getVersionStrings() 87 | { 88 | return $this->getParameter('versionStrings'); 89 | } 90 | 91 | /** 92 | * @param string $value 93 | * @return $this 94 | */ 95 | public function setVersionStrings(array $values) 96 | { 97 | return $this->setParameter('versionStrings', $values); 98 | } 99 | 100 | /** 101 | * @param string $value 102 | * @return $this 103 | */ 104 | public function addVersionString($value) 105 | { 106 | $versionStrings = $this->getVersionStrings() ?: []; 107 | $versionStrings[] = str_replace([" ", "\t", "\n", "\r"], '-', $value); 108 | 109 | return $this->setVersionStrings($versionStrings); 110 | } 111 | 112 | /** 113 | * @param array $parameters 114 | * @return FetchIssuersRequest 115 | */ 116 | public function fetchIssuers(array $parameters = []) 117 | { 118 | /** @var FetchIssuersRequest $request */ 119 | $request = $this->createRequest(FetchIssuersRequest::class, $parameters); 120 | 121 | return $request; 122 | } 123 | 124 | /** 125 | * @param array $parameters 126 | * @return FetchPaymentMethodsRequest 127 | */ 128 | public function fetchPaymentMethods(array $parameters = []) 129 | { 130 | /** @var FetchPaymentMethodsRequest $request */ 131 | $request = $this->createRequest(FetchPaymentMethodsRequest::class, $parameters); 132 | 133 | return $request; 134 | } 135 | 136 | /** 137 | * @param array $parameters 138 | * @return FetchTransactionRequest 139 | */ 140 | public function fetchTransaction(array $parameters = []) 141 | { 142 | /** @var FetchTransactionRequest $request */ 143 | $request = $this->createRequest(FetchTransactionRequest::class, $parameters); 144 | 145 | return $request; 146 | } 147 | 148 | /** 149 | * @param array $parameters 150 | * @return PurchaseRequest 151 | */ 152 | public function purchase(array $parameters = []) 153 | { 154 | /** @var PurchaseRequest $request */ 155 | $request = $this->createRequest(PurchaseRequest::class, $parameters); 156 | 157 | return $request; 158 | } 159 | 160 | /** 161 | * @param array $parameters 162 | * @return CompletePurchaseRequest 163 | */ 164 | public function completePurchase(array $parameters = []) 165 | { 166 | /** @var CompletePurchaseRequest $request */ 167 | $request = $this->createRequest(CompletePurchaseRequest::class, $parameters); 168 | 169 | return $request; 170 | } 171 | 172 | /** 173 | * @param array $parameters 174 | * @return RefundRequest 175 | */ 176 | public function refund(array $parameters = []) 177 | { 178 | /** @var RefundRequest $request */ 179 | $request = $this->createRequest(RefundRequest::class, $parameters); 180 | 181 | return $request; 182 | } 183 | 184 | /** 185 | * @param array $parameters 186 | * @return CreateOrderRequest 187 | */ 188 | public function createOrder(array $parameters = []) 189 | { 190 | /** @var CreateOrderRequest $request */ 191 | $request = $this->createRequest(CreateOrderRequest::class, $parameters); 192 | 193 | return $request; 194 | } 195 | 196 | 197 | /** 198 | * @param array $parameters 199 | * @return FetchOrderRequest 200 | */ 201 | public function fetchOrder(array $parameters = []) 202 | { 203 | /** @var FetchOrderRequest $request */ 204 | $request = $this->createRequest(FetchOrderRequest::class, $parameters); 205 | 206 | return $request; 207 | } 208 | 209 | 210 | /** 211 | * @param array $parameters 212 | * @return CompleteOrderRequest 213 | */ 214 | public function completeOrder(array $parameters = []) 215 | { 216 | /** @var CompleteOrderRequest $request */ 217 | $request = $this->createRequest(CompleteOrderRequest::class, $parameters); 218 | 219 | return $request; 220 | } 221 | 222 | /** 223 | * @param array $parameters 224 | * @return CreateShipmentRequest 225 | */ 226 | public function createShipment(array $parameters = []) 227 | { 228 | /** @var CreateShipmentRequest $request */ 229 | $request = $this->createRequest(CreateShipmentRequest::class, $parameters); 230 | 231 | return $request; 232 | } 233 | 234 | /** 235 | * @param array $parameters 236 | * @return CreateCustomerRequest 237 | */ 238 | public function createCustomer(array $parameters = []) 239 | { 240 | /** @var CreateCustomerRequest $request */ 241 | $request = $this->createRequest(CreateCustomerRequest::class, $parameters); 242 | 243 | return $request; 244 | } 245 | 246 | /** 247 | * @param array $parameters 248 | * @return UpdateCustomerRequest 249 | */ 250 | public function updateCustomer(array $parameters = []) 251 | { 252 | /** @var UpdateCustomerRequest $request */ 253 | $request = $this->createRequest(UpdateCustomerRequest::class, $parameters); 254 | 255 | return $request; 256 | } 257 | 258 | /** 259 | * @param array $parameters 260 | * @return FetchCustomerRequest 261 | */ 262 | public function fetchCustomer(array $parameters = []) 263 | { 264 | /** @var FetchCustomerRequest $request */ 265 | $request = $this->createRequest(FetchCustomerRequest::class, $parameters); 266 | 267 | return $request; 268 | } 269 | 270 | /** 271 | * @param array $parameters 272 | * @return FetchCustomerMandatesRequest 273 | */ 274 | public function fetchCustomerMandates(array $parameters = []) 275 | { 276 | return $this->createRequest(FetchCustomerMandatesRequest::class, $parameters); 277 | } 278 | 279 | /** 280 | * @param array $parameters 281 | * @return CreateCustomerMandateRequest 282 | */ 283 | public function createCustomerMandate(array $parameters = []) 284 | { 285 | return $this->createRequest(CreateCustomerMandateRequest::class, $parameters); 286 | } 287 | 288 | /** 289 | * @param array $parameters 290 | * @return RevokeCustomerMandateRequest 291 | */ 292 | public function revokeCustomerMandate(array $parameters = []) 293 | { 294 | return $this->createRequest(RevokeCustomerMandateRequest::class, $parameters); 295 | } 296 | 297 | /** 298 | * @param array $parameters 299 | * @return CancelOrderRequest 300 | */ 301 | public function void(array $parameters = []) 302 | { 303 | return $this->createRequest(CancelOrderRequest::class, $parameters); 304 | } 305 | } 306 | -------------------------------------------------------------------------------- /src/Item.php: -------------------------------------------------------------------------------- 1 | parameters->set($key, $value); 21 | 22 | return $this; 23 | } 24 | 25 | public function getId() 26 | { 27 | return $this->getParameter('id'); 28 | } 29 | 30 | public function setId($value) 31 | { 32 | return $this->setParameter('id', $value); 33 | } 34 | 35 | public function getUnitPrice() 36 | { 37 | return $this->getParameter('unitPrice'); 38 | } 39 | 40 | public function setUnitPrice($value) 41 | { 42 | return $this->setParameter('unitPrice', $value); 43 | } 44 | 45 | public function getDiscountAmount() 46 | { 47 | return $this->getParameter('discountAmount'); 48 | } 49 | 50 | public function setDiscountAmount($value) 51 | { 52 | return $this->setParameter('discountAmount', $value); 53 | } 54 | 55 | public function getTotalAmount() 56 | { 57 | return $this->getParameter('totalAmount'); 58 | } 59 | 60 | public function setTotalAmount($value) 61 | { 62 | return $this->setParameter('totalAmount', $value); 63 | } 64 | 65 | public function getVatRate() 66 | { 67 | return $this->getParameter('vatRate'); 68 | } 69 | 70 | public function setVatRate($value) 71 | { 72 | return $this->setParameter('vatRate', $value); 73 | } 74 | 75 | public function getVatAmount() 76 | { 77 | return $this->getParameter('vatAmount'); 78 | } 79 | 80 | public function setVatAmount($value) 81 | { 82 | return $this->setParameter('vatAmount', $value); 83 | } 84 | 85 | public function getSku() 86 | { 87 | return $this->getParameter('sku'); 88 | } 89 | 90 | public function setSku($value) 91 | { 92 | return $this->setParameter('sku', $value); 93 | } 94 | 95 | public function getType() 96 | { 97 | return $this->getParameter('type'); 98 | } 99 | 100 | public function setType($value) 101 | { 102 | return $this->setParameter('type', $value); 103 | } 104 | 105 | public function getProductUrl() 106 | { 107 | return $this->getParameter('productUrl'); 108 | } 109 | 110 | public function setProductUrl($value) 111 | { 112 | return $this->setParameter('productUrl', $value); 113 | } 114 | 115 | public function getImageUrl() 116 | { 117 | return $this->getParameter('imageUrl'); 118 | } 119 | 120 | public function setImageUrl($value) 121 | { 122 | return $this->setParameter('imageUrl', $value); 123 | } 124 | 125 | public function getResource() 126 | { 127 | return $this->getParameter('resource'); 128 | } 129 | 130 | public function setResource($value) 131 | { 132 | return $this->setParameter('resource', $value); 133 | } 134 | 135 | public function getStatus() 136 | { 137 | return $this->getParameter('status'); 138 | } 139 | 140 | public function setStatus($value) 141 | { 142 | return $this->setParameter('status', $value); 143 | } 144 | 145 | 146 | public function getIsCancelable() 147 | { 148 | return $this->getParameter('isCancelable'); 149 | } 150 | 151 | public function setIsCancelable($value) 152 | { 153 | return $this->setParameter('isCancelable', $value); 154 | } 155 | 156 | public function getOrderId() 157 | { 158 | return $this->getParameter('orderId'); 159 | } 160 | 161 | public function setOrderId($value) 162 | { 163 | return $this->setParameter('orderId', $value); 164 | } 165 | 166 | public function getQuantityShipped() 167 | { 168 | return $this->getParameter('quantityShipped'); 169 | } 170 | 171 | public function setQuantityShipped($value) 172 | { 173 | return $this->setParameter('quantityShipped', $value); 174 | } 175 | 176 | public function getAmountShipped() 177 | { 178 | return $this->getParameter('amountShipped'); 179 | } 180 | 181 | public function setAmountShipped($value) 182 | { 183 | return $this->setParameter('amountShipped', $value); 184 | } 185 | 186 | public function getQuantityRefunded() 187 | { 188 | return $this->getParameter('quantityRefunded'); 189 | } 190 | 191 | public function setQuantityRefunded($value) 192 | { 193 | return $this->setParameter('quantityRefunded', $value); 194 | } 195 | 196 | public function getAmountRefunded() 197 | { 198 | return $this->getParameter('amountRefunded'); 199 | } 200 | 201 | public function setAmountRefunded($value) 202 | { 203 | return $this->setParameter('amountRefunded', $value); 204 | } 205 | 206 | public function getQuantityCanceled() 207 | { 208 | return $this->getParameter('quantityCanceled'); 209 | } 210 | 211 | public function setQuantityCanceled($value) 212 | { 213 | return $this->setParameter('quantityCanceled', $value); 214 | } 215 | 216 | public function getAmountCanceled() 217 | { 218 | return $this->getParameter('amountCanceled'); 219 | } 220 | 221 | public function setAmountCanceled($value) 222 | { 223 | return $this->setParameter('amountCanceled', $value); 224 | } 225 | 226 | public function getShippableQuantity() 227 | { 228 | return $this->getParameter('shippableQuantity'); 229 | } 230 | 231 | public function setShippableQuantity($value) 232 | { 233 | return $this->setParameter('shippableQuantity', $value); 234 | } 235 | 236 | public function getRefundableQuantity() 237 | { 238 | return $this->getParameter('refundableQuantity'); 239 | } 240 | 241 | public function setRefundableQuantity($value) 242 | { 243 | return $this->setParameter('refundableQuantity', $value); 244 | } 245 | 246 | public function getCancelableQuantity() 247 | { 248 | return $this->getParameter('cancelableQuantity'); 249 | } 250 | 251 | public function setCancelableQuantity($value) 252 | { 253 | return $this->setParameter('cancelableQuantity', $value); 254 | } 255 | 256 | public function getCreatedAt() 257 | { 258 | return $this->getParameter('createdAt'); 259 | } 260 | 261 | public function setCreatedAt($value) 262 | { 263 | return $this->setParameter('createdAt', $value); 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /src/Message/Request/AbstractMollieRequest.php: -------------------------------------------------------------------------------- 1 | getParameter('apiKey'); 37 | } 38 | 39 | /** 40 | * @param string $value 41 | * @return $this 42 | */ 43 | public function setApiKey($value) 44 | { 45 | return $this->setParameter('apiKey', $value); 46 | } 47 | 48 | /** 49 | * @return array|null 50 | */ 51 | public function getVersionStrings() 52 | { 53 | return $this->getParameter('versionStrings'); 54 | } 55 | 56 | /** 57 | * @param string $value 58 | * @return $this 59 | */ 60 | public function setVersionStrings(array $values) 61 | { 62 | return $this->setParameter('versionStrings', $values); 63 | } 64 | 65 | /** 66 | * @param string $value 67 | * @return $this 68 | */ 69 | public function setTransactionId($value) 70 | { 71 | return $this->setParameter('transactionId', $value); 72 | } 73 | 74 | /** 75 | * @return string 76 | */ 77 | public function getTransactionId() 78 | { 79 | return $this->getParameter('transactionId'); 80 | } 81 | 82 | /** 83 | * Set the items in this order 84 | * 85 | * @param Item[] $items An array of items in this order 86 | * @return $this 87 | */ 88 | public function setItems($items) 89 | { 90 | $orderItems = []; 91 | foreach ($items as $item) { 92 | if (is_array($item)) { 93 | $orderItems[] = new Item($item); 94 | } elseif (! ($item instanceof Item)) { 95 | throw new \InvalidArgumentException('Item should be an instance of ' . Item::class); 96 | } 97 | } 98 | 99 | return parent::setItems($orderItems); 100 | } 101 | 102 | /** 103 | * @param string $method 104 | * @param string $endpoint 105 | * @param array $data 106 | * @return array 107 | */ 108 | protected function sendRequest($method, $endpoint, ?array $data = null) 109 | { 110 | $versions = [ 111 | 'Omnipay-Mollie/' . Gateway::GATEWAY_VERSION, 112 | 'PHP/' . phpversion(), 113 | ]; 114 | 115 | if ($customVersions = $this->getParameter('versionStrings')) { 116 | $versions = array_merge($versions, $customVersions); 117 | } 118 | 119 | $headers = [ 120 | 'Accept' => "application/json", 121 | 'Content-Type' => "application/json", 122 | 'Authorization' => 'Bearer ' . $this->getApiKey(), 123 | 'User-Agent' => implode(' ', $versions), 124 | ]; 125 | 126 | if (function_exists("php_uname")) { 127 | $headers['X-Mollie-Client-Info'] = php_uname(); 128 | } 129 | 130 | $response = $this->httpClient->request( 131 | $method, 132 | $this->baseUrl . $this->apiVersion . $endpoint, 133 | $headers, 134 | ($data === null || $data === []) ? null : json_encode($data) 135 | ); 136 | 137 | return json_decode($response->getBody(), true); 138 | } 139 | 140 | 141 | protected function createAmountObject($amount) 142 | { 143 | return isset($amount) ? [ 144 | 'currency' => $this->getCurrency(), 145 | 'value' => $this->formatCurrency($amount), 146 | ] : null; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/Message/Request/CancelOrderRequest.php: -------------------------------------------------------------------------------- 1 | validate('apiKey', 'transactionReference'); 21 | 22 | return []; 23 | } 24 | 25 | /** 26 | * @inheritdoc 27 | */ 28 | public function sendData($data) 29 | { 30 | return $this->response = new CancelOrderResponse( 31 | $this, 32 | $this->sendRequest(self::DELETE, '/orders/'.$this->getTransactionReference(), $data) 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Message/Request/CompleteOrderRequest.php: -------------------------------------------------------------------------------- 1 | validate('apiKey'); 23 | 24 | $data = []; 25 | $data['id'] = $this->getTransactionReference(); 26 | 27 | if (!isset($data['id'])) { 28 | $data['id'] = $this->httpRequest->request->get('id'); 29 | } 30 | 31 | if (empty($data['id'])) { 32 | throw new InvalidRequestException("The transactionReference parameter is required"); 33 | } 34 | 35 | return $data; 36 | } 37 | 38 | /** 39 | * @param array $data 40 | * @return CompleteOrderResponse 41 | */ 42 | public function sendData($data) 43 | { 44 | $response = $this->sendRequest(self::GET, '/orders/' . $data['id']); 45 | 46 | return $this->response = new CompleteOrderResponse($this, $response); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Message/Request/CompletePurchaseRequest.php: -------------------------------------------------------------------------------- 1 | validate('apiKey'); 23 | 24 | $data = []; 25 | $data['id'] = $this->getTransactionReference(); 26 | 27 | if (!isset($data['id'])) { 28 | $data['id'] = $this->httpRequest->request->get('id'); 29 | } 30 | 31 | if (empty($data['id'])) { 32 | throw new InvalidRequestException("The transactionReference parameter is required"); 33 | } 34 | 35 | return $data; 36 | } 37 | 38 | /** 39 | * @param array $data 40 | * @return CompletePurchaseResponse 41 | */ 42 | public function sendData($data) 43 | { 44 | $response = $this->sendRequest(self::GET, '/payments/' . $data['id']); 45 | 46 | return $this->response = new CompletePurchaseResponse($this, $response); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Message/Request/CreateCustomerMandateRequest.php: -------------------------------------------------------------------------------- 1 | getParameter('method'); 23 | } 24 | 25 | /** 26 | * @param string $method 27 | * @return AbstractRequest 28 | */ 29 | public function setMethod($method) 30 | { 31 | return $this->setParameter('method', $method); 32 | } 33 | 34 | /** 35 | * @return string 36 | */ 37 | public function getConsumerName() 38 | { 39 | return $this->getParameter('consumerName'); 40 | } 41 | 42 | /** 43 | * @param string $consumerName 44 | * @return AbstractRequest 45 | */ 46 | public function setConsumerName($consumerName) 47 | { 48 | return $this->setParameter('consumerName', $consumerName); 49 | } 50 | 51 | /** 52 | * @return string 53 | */ 54 | public function getConsumerAccount() 55 | { 56 | return $this->getParameter('consumerAccount'); 57 | } 58 | 59 | /** 60 | * @param string $consumerAccount 61 | * @return AbstractRequest 62 | */ 63 | public function setConsumerAccount($consumerAccount) 64 | { 65 | return $this->setParameter('consumerAccount', $consumerAccount); 66 | } 67 | 68 | /** 69 | * @return string 70 | */ 71 | public function getConsumerBic() 72 | { 73 | return $this->getParameter('consumerBic'); 74 | } 75 | 76 | /** 77 | * @param string $consumerBic 78 | * @return AbstractRequest 79 | */ 80 | public function setConsumerBic($consumerBic) 81 | { 82 | return $this->setParameter('consumerBic', $consumerBic); 83 | } 84 | 85 | /** 86 | * @return string 87 | */ 88 | public function getSignatureDate() 89 | { 90 | return $this->getParameter('signatureDate'); 91 | } 92 | 93 | /** 94 | * @param string $signatureDate 95 | * @return AbstractRequest 96 | */ 97 | public function setSignatureDate($signatureDate) 98 | { 99 | return $this->setParameter('signatureDate', $signatureDate); 100 | } 101 | 102 | /** 103 | * @return string 104 | */ 105 | public function getMandateReference() 106 | { 107 | return $this->getParameter('mandateReference'); 108 | } 109 | 110 | /** 111 | * @param string $mandateReference 112 | * @return AbstractRequest 113 | */ 114 | public function setMandateReference($mandateReference) 115 | { 116 | return $this->setParameter('mandateReference', $mandateReference); 117 | } 118 | 119 | /** 120 | * @return string 121 | */ 122 | public function getCustomerReference() 123 | { 124 | return $this->getParameter('customerReference'); 125 | } 126 | 127 | /** 128 | * @param string $customerReference 129 | * @return AbstractRequest 130 | */ 131 | public function setCustomerReference($customerReference) 132 | { 133 | return $this->setParameter('customerReference', $customerReference); 134 | } 135 | 136 | 137 | /** 138 | * @return array 139 | * @throws InvalidRequestException 140 | */ 141 | public function getData() 142 | { 143 | $this->validate('apiKey', 'customerReference', 'method', 'consumerName', 'consumerAccount'); 144 | 145 | $data = array(); 146 | $data['method'] = $this->getMethod(); 147 | $data['consumerName'] = $this->getConsumerName(); 148 | $data['consumerAccount'] = $this->getConsumerAccount(); 149 | 150 | if ($this->getConsumerBic()) { 151 | $data['consumerBic'] = $this->getConsumerBic(); 152 | } 153 | 154 | if ($this->getSignatureDate()) { 155 | $data['signatureDate'] = $this->getSignatureDate(); 156 | } 157 | 158 | if ($this->getMandateReference()) { 159 | $data['mandateReference'] = $this->getMandateReference(); 160 | } 161 | 162 | return $data; 163 | } 164 | 165 | /** 166 | * @param array $data 167 | * @return CreateCustomerMandateResponse 168 | */ 169 | public function sendData($data) 170 | { 171 | $response = $this->sendRequest(self::POST, "/customers/{$this->getCustomerReference()}/mandates", $data); 172 | 173 | return $this->response = new CreateCustomerMandateResponse($this, $response); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/Message/Request/CreateCustomerRequest.php: -------------------------------------------------------------------------------- 1 | getParameter('email'); 25 | } 26 | 27 | /** 28 | * @param string $value 29 | * @return AbstractRequest 30 | */ 31 | public function setEmail($value) 32 | { 33 | return $this->setParameter('email', $value); 34 | } 35 | 36 | /** 37 | * Get the customer's locale. 38 | * 39 | * Possible values: de_DE, en_US, es_ES, fr_FR, nl_BE, fr_BE, nl_NL. 40 | * 41 | * @return string 42 | */ 43 | public function getLocale() 44 | { 45 | return $this->getParameter('locale'); 46 | } 47 | 48 | /** 49 | * Optional value. 50 | * 51 | * @param string $value 52 | * @return AbstractRequest 53 | */ 54 | public function setLocale($value) 55 | { 56 | return $this->setParameter('locale', $value); 57 | } 58 | 59 | /** 60 | * Get the customer's metadata. 61 | * 62 | * @return array 63 | */ 64 | public function getMetadata() 65 | { 66 | return $this->getParameter('metadata'); 67 | } 68 | 69 | /** 70 | * Optional value. 71 | * 72 | * @param array $value 73 | * @return AbstractRequest 74 | */ 75 | public function setMetadata($value) 76 | { 77 | return $this->setParameter('metadata', $value); 78 | } 79 | 80 | /** 81 | * @return array 82 | * @throws InvalidRequestException 83 | */ 84 | public function getData() 85 | { 86 | $this->validate('apiKey'); 87 | 88 | $data = []; 89 | $data['name'] = $this->getDescription(); 90 | $data['email'] = $this->getEmail(); 91 | $data['locale'] = $this->getLocale(); 92 | 93 | if ($this->getMetadata()) { 94 | $data['metadata'] = $this->getMetadata(); 95 | } 96 | 97 | return $data; 98 | } 99 | 100 | /** 101 | * @param array $data 102 | * @return CreateCustomerResponse 103 | */ 104 | public function sendData($data) 105 | { 106 | $response = $this->sendRequest(self::POST, '/customers', $data); 107 | 108 | return $this->response = new CreateCustomerResponse($this, $response); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/Message/Request/CreateOrderRequest.php: -------------------------------------------------------------------------------- 1 | getParameter('metadata'); 34 | } 35 | 36 | /** 37 | * @param array $value 38 | * @return $this 39 | */ 40 | public function setMetadata(array $value) 41 | { 42 | return $this->setParameter('metadata', $value); 43 | } 44 | 45 | /** 46 | * @return string 47 | */ 48 | public function getLocale() 49 | { 50 | return $this->getParameter('locale'); 51 | } 52 | 53 | /** 54 | * @param string $value 55 | * @return $this 56 | */ 57 | public function setLocale($value) 58 | { 59 | return $this->setParameter('locale', $value); 60 | } 61 | 62 | /** 63 | * @return string 64 | */ 65 | public function getOrderNumber() 66 | { 67 | return $this->getParameter('orderNumber'); 68 | } 69 | 70 | /** 71 | * @param string $value 72 | * @return $this 73 | */ 74 | public function setOrderNumber($value) 75 | { 76 | return $this->setParameter('orderNumber', $value); 77 | } 78 | 79 | /** 80 | * @return string 81 | */ 82 | public function getBillingEmail() 83 | { 84 | return $this->getParameter('billingEmail'); 85 | } 86 | 87 | /** 88 | * @param string $value 89 | * @return $this 90 | */ 91 | public function setBillingEmail($value) 92 | { 93 | return $this->setParameter('billingEmail', $value); 94 | } 95 | 96 | /** 97 | * @return string 98 | */ 99 | public function getCustomerReference() 100 | { 101 | return $this->getParameter('customerReference'); 102 | } 103 | 104 | /** 105 | * @param string $value 106 | * @return $this 107 | */ 108 | public function setCustomerReference($value) 109 | { 110 | return $this->setParameter('customerReference', $value); 111 | } 112 | 113 | /** 114 | * @return string 115 | */ 116 | public function getSequenceType() 117 | { 118 | return $this->getParameter('sequenceType'); 119 | } 120 | 121 | /** 122 | * @param string $value 123 | * @return $this 124 | */ 125 | public function setSequenceType($value) 126 | { 127 | return $this->setParameter('sequenceType', $value); 128 | } 129 | 130 | /** 131 | * @return string 132 | */ 133 | public function getCardToken() 134 | { 135 | return $this->getParameter('cardToken'); 136 | } 137 | 138 | /** 139 | * @param string $value 140 | * @return $this 141 | */ 142 | public function setCardToken($value) 143 | { 144 | return $this->setParameter('cardToken', $value); 145 | } 146 | 147 | /** 148 | * Alias for lines 149 | * 150 | * @param $items 151 | * @return $this 152 | */ 153 | public function setLines($items) 154 | { 155 | return $this->setItems($items); 156 | } 157 | 158 | /** 159 | * A list of items in this order 160 | * 161 | * @return Item[]|null A bag containing items in this order 162 | */ 163 | public function getItems() 164 | { 165 | return $this->getParameter('items'); 166 | } 167 | 168 | /** 169 | * @return array 170 | * @throws InvalidRequestException 171 | */ 172 | public function getData() 173 | { 174 | $this->validate('apiKey', 'amount', 'locale', 'card', 'items', 'currency', 'orderNumber', 'returnUrl'); 175 | 176 | $data = []; 177 | $data['amount'] = [ 178 | 'value' => $this->getAmount(), 179 | 'currency' => $this->getCurrency() 180 | ]; 181 | 182 | if ($card = $this->getCard()) { 183 | $data += $this->getCardData($card); 184 | } 185 | 186 | $data['metadata'] = $this->getMetadata(); 187 | if ($this->getTransactionId()) { 188 | $data['metadata']['transactionId'] = $this->getTransactionId(); 189 | } 190 | 191 | if ($card && $birthday = $card->getBirthday()) { 192 | $data['consumerDateOfBirth'] = $birthday; 193 | } 194 | 195 | $data['locale'] = $this->getLocale(); 196 | $data['orderNumber'] = (string) $this->getOrderNumber(); 197 | $data['redirectUrl'] = $this->getReturnUrl(); 198 | $data['webhookUrl'] = $this->getNotifyUrl(); 199 | $data['method'] = $this->getPaymentMethod(); 200 | 201 | $data['lines'] = []; 202 | if ($items = $this->getItems()) { 203 | $data['lines'] = $this->getLines($items); 204 | } 205 | 206 | $data['payment'] = []; 207 | if ($issuer = $this->getIssuer()) { 208 | $data['payment']['issuer'] = $issuer; 209 | } 210 | 211 | if ($customerReference = $this->getCustomerReference()) { 212 | $data['payment']['customerId'] = $customerReference; 213 | } 214 | 215 | if ($sequenceType = $this->getSequenceType()) { 216 | $data['payment']['sequenceType'] = $sequenceType; 217 | } 218 | 219 | if ($cardToken = $this->getCardToken()) { 220 | $data['payment']['cardToken'] = $cardToken; 221 | } 222 | 223 | return array_filter($data); 224 | } 225 | 226 | protected function getCardData(CreditCard $card) 227 | { 228 | $data = []; 229 | 230 | $data['billingAddress'] = array_filter([ 231 | 'organizationName' => $card->getCompany(), 232 | 'streetAndNumber' => $card->getAddress1(), 233 | 'streetAdditional' => $card->getAddress2(), 234 | 'city' => $card->getCity(), 235 | 'region' => $card->getState(), 236 | 'postalCode' => $card->getPostcode(), 237 | 'country' => $card->getCountry(), 238 | 'title' => $card->getTitle(), 239 | 'givenName' => $card->getFirstName(), 240 | 'familyName' => $card->getLastName(), 241 | 'email' => $this->getBillingEmail() ?: $card->getEmail(), 242 | 'phone' => $card->getPhone(), 243 | ]); 244 | 245 | if ($card->getShippingAddress1()) { 246 | $data['shippingAddress'] = array_filter([ 247 | 'organizationName' => $card->getCompany(), 248 | 'streetAndNumber' => $card->getShippingAddress1(), 249 | 'streetAdditional' => $card->getShippingAddress2(), 250 | 'city' => $card->getShippingCity(), 251 | 'region' => $card->getShippingState(), 252 | 'postalCode' => $card->getShippingPostcode(), 253 | 'country' => $card->getShippingCountry(), 254 | 'title' => $card->getShippingTitle(), 255 | 'givenName' => $card->getShippingFirstName(), 256 | 'familyName' => $card->getShippingLastName(), 257 | 'email' => $card->getEmail(), 258 | 'phone' => $card->getShippingPhone(), 259 | ]); 260 | } 261 | 262 | return $data; 263 | } 264 | 265 | protected function getLines(ItemBag $items) 266 | { 267 | $lines = []; 268 | foreach ($items as $item) { 269 | $vatRate = $item->getVatRate(); 270 | $totalAmount = $item->getTotalAmount(); 271 | $vatAmount = $item->getVatAmount(); 272 | 273 | if (null === $totalAmount) { 274 | $totalAmount = $item->getQuantity() * $item->getPrice(); 275 | } 276 | 277 | if (null === $vatAmount) { 278 | $vatAmount = round($totalAmount * ($vatRate / (100 + $vatRate)), $this->getCurrencyDecimalPlaces()); 279 | } 280 | 281 | $data = [ 282 | 'type' => $item->getType(), 283 | 'sku' => $item->getSku(), 284 | 'name' => $item->getName(), 285 | 'productUrl' => $item->getProductUrl(), 286 | 'imageUrl' => $item->getImageUrl(), 287 | 'quantity' => (int) $item->getQuantity(), 288 | 'vatRate' => $vatRate, 289 | 'unitPrice' => $this->createAmountObject($item->getUnitPrice()), 290 | 'totalAmount' => $this->createAmountObject($totalAmount), 291 | 'discountAmount' => $this->createAmountObject($item->getDiscountAmount()), 292 | 'vatAmount' => $this->createAmountObject($vatAmount), 293 | ]; 294 | 295 | // Strip null values 296 | $lines[] = array_filter($data); 297 | } 298 | 299 | return $lines; 300 | } 301 | 302 | /** 303 | * @return bool 304 | */ 305 | public function hasIncludePayments() 306 | { 307 | return (bool) $this->getParameter('includePayments'); 308 | } 309 | 310 | /** 311 | * @param array $data 312 | * @return ResponseInterface|PurchaseResponse 313 | */ 314 | public function sendData($data) 315 | { 316 | $response = $this->sendRequest( 317 | self::POST, 318 | \sprintf( 319 | '/orders%s', 320 | $this->hasIncludePayments() ? '?embed=payments' : '' 321 | ), 322 | $data 323 | ); 324 | 325 | return $this->response = new CreateOrderResponse($this, $response); 326 | } 327 | 328 | /** 329 | * @param bool $includePayments 330 | * @return self 331 | */ 332 | public function setIncludePayments($includePayments) 333 | { 334 | return $this->setParameter('includePayments', $includePayments); 335 | } 336 | } 337 | -------------------------------------------------------------------------------- /src/Message/Request/CreateShipmentRequest.php: -------------------------------------------------------------------------------- 1 | getParameter('tracking'); 22 | } 23 | 24 | /** 25 | * @param array $value 26 | * @return $this 27 | */ 28 | public function setTracking(array $value) 29 | { 30 | return $this->setParameter('tracking', $value); 31 | } 32 | 33 | 34 | /** 35 | * @return array 36 | * @throws InvalidRequestException 37 | */ 38 | public function getData() 39 | { 40 | $this->validate('apiKey', 'transactionReference'); 41 | 42 | $data = []; 43 | $data['lines'] = []; 44 | 45 | if ($items = $this->getItems()) { 46 | foreach ($items as $item) { 47 | $data['lines'][] = array_filter([ 48 | 'id' => $item->getId(), 49 | 'quantity' => $item->getQuantity(), 50 | ]); 51 | } 52 | } 53 | 54 | if ($tracking = $this->getTracking()) { 55 | $data['tracking'] = $tracking; 56 | } 57 | 58 | return $data; 59 | } 60 | 61 | /** 62 | * @param array $data 63 | * @return CreateShipmentResponse 64 | */ 65 | public function sendData($data) 66 | { 67 | $response = $this->sendRequest(self::POST, '/orders/' . $this->getTransactionReference() . '/shipments', $data); 68 | 69 | return $this->response = new CreateShipmentResponse($this, $response); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Message/Request/FetchCustomerMandatesRequest.php: -------------------------------------------------------------------------------- 1 | getParameter('customerReference'); 23 | } 24 | 25 | /** 26 | * @param string $value 27 | * @return AbstractRequest 28 | */ 29 | public function setCustomerReference($value) 30 | { 31 | return $this->setParameter('customerReference', $value); 32 | } 33 | 34 | /** 35 | * @return array 36 | * @throws InvalidRequestException 37 | */ 38 | public function getData() 39 | { 40 | $this->validate('apiKey', 'customerReference'); 41 | 42 | return array(); 43 | } 44 | 45 | /** 46 | * @param array $data 47 | * @return FetchCustomerMandatesResponse 48 | */ 49 | public function sendData($data) 50 | { 51 | $response = $this->sendRequest(self::GET, "/customers/{$this->getCustomerReference()}/mandates", $data); 52 | 53 | return $this->response = new FetchCustomerMandatesResponse($this, $response); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Message/Request/FetchCustomerRequest.php: -------------------------------------------------------------------------------- 1 | getParameter('customerReference'); 23 | } 24 | 25 | /** 26 | * @param string $value 27 | * @return AbstractRequest 28 | */ 29 | public function setCustomerReference($value) 30 | { 31 | return $this->setParameter('customerReference', $value); 32 | } 33 | 34 | /** 35 | * @return array 36 | * @throws InvalidRequestException 37 | */ 38 | public function getData() 39 | { 40 | $this->validate('apiKey', 'customerReference'); 41 | 42 | return []; 43 | } 44 | 45 | /** 46 | * @param array $data 47 | * @return FetchCustomerResponse 48 | */ 49 | public function sendData($data) 50 | { 51 | $response = $this->sendRequest(self::GET, '/customers/' . $this->getCustomerReference(), $data); 52 | 53 | return $this->response = new FetchCustomerResponse($this, $response); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Message/Request/FetchIssuersRequest.php: -------------------------------------------------------------------------------- 1 | validate('apiKey'); 32 | 33 | return []; 34 | } 35 | 36 | /** 37 | * @param array $data 38 | * @return ResponseInterface|FetchIssuersResponse 39 | */ 40 | public function sendData($data) 41 | { 42 | $response = $this->sendRequest(self::GET, $this->endpoint); 43 | 44 | return $this->response = new FetchIssuersResponse($this, $response); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Message/Request/FetchOrderRequest.php: -------------------------------------------------------------------------------- 1 | validate('apiKey', 'transactionReference'); 23 | 24 | $data = []; 25 | $data['id'] = $this->getTransactionReference(); 26 | 27 | return $data; 28 | } 29 | 30 | /** 31 | * @return bool 32 | */ 33 | public function hasIncludePayments() 34 | { 35 | return (bool) $this->getParameter('includePayments'); 36 | } 37 | 38 | /** 39 | * @param array $data 40 | * @return FetchOrderResponse 41 | */ 42 | public function sendData($data) 43 | { 44 | $response = $this->sendRequest( 45 | self::GET, 46 | \sprintf( 47 | '/orders/%s%s', 48 | $data['id'], 49 | $this->hasIncludePayments() ? '?embed=payments' : '' 50 | ) 51 | ); 52 | 53 | return $this->response = new FetchOrderResponse($this, $response); 54 | } 55 | 56 | /** 57 | * @param bool $includePayments 58 | * @return self 59 | */ 60 | public function setIncludePayments($includePayments) 61 | { 62 | return $this->setParameter('includePayments', $includePayments); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Message/Request/FetchPaymentMethodsRequest.php: -------------------------------------------------------------------------------- 1 | setParameter('billingCountry', $billingCountry); 24 | } 25 | 26 | /** 27 | * @return string 28 | */ 29 | public function getBillingCountry() 30 | { 31 | return $this->getParameter('billingCountry'); 32 | } 33 | 34 | /** 35 | * @param string $includeWallets 36 | * @return $this 37 | */ 38 | public function setIncludeWallets($includeWallets) 39 | { 40 | return $this->setParameter('includeWallets', $includeWallets); 41 | } 42 | 43 | /** 44 | * @return string 45 | */ 46 | public function getIncludeWallets() 47 | { 48 | return $this->getParameter('includeWallets'); 49 | } 50 | 51 | /** 52 | * @param string $locale 53 | * @return $this 54 | */ 55 | public function setLocale($locale) 56 | { 57 | return $this->setParameter('locale', $locale); 58 | } 59 | 60 | /** 61 | * @return string 62 | */ 63 | public function getLocale() 64 | { 65 | return $this->getParameter('locale'); 66 | } 67 | 68 | /** 69 | * @param string $resource 70 | * @return $this 71 | */ 72 | public function setResource($resource) 73 | { 74 | return $this->setParameter('resource', $resource); 75 | } 76 | 77 | /** 78 | * @return string 79 | */ 80 | public function getResource() 81 | { 82 | return $this->getParameter('resource'); 83 | } 84 | 85 | /** 86 | * @param $sequenceType 87 | * @return $this 88 | */ 89 | public function setSequenceType($sequenceType) 90 | { 91 | return $this->setParameter('sequenceType', $sequenceType); 92 | } 93 | 94 | /** 95 | * @return string 96 | */ 97 | public function getSequenceType() 98 | { 99 | return $this->getParameter('sequenceType'); 100 | } 101 | 102 | /** 103 | * @return array 104 | * @throws InvalidRequestException 105 | */ 106 | public function getData() 107 | { 108 | $this->validate('apiKey'); 109 | 110 | // Currency and amount are optional but both required when either one is supplied 111 | $amount = null; 112 | if ($this->getAmount() || $this->getCurrency()) { 113 | $this->validate('amount', 'currency'); 114 | 115 | $amount = [ 116 | 'value' => $this->getAmount(), 117 | 'currency' => $this->getCurrency(), 118 | ]; 119 | } 120 | 121 | return [ 122 | 'amount' => $amount, 123 | 'billingCountry' => $this->getBillingCountry(), 124 | 'locale' => $this->getLocale(), 125 | 'resource' => $this->getResource(), 126 | 'includeWallets' => $this->getIncludeWallets(), 127 | 'sequenceType' => $this->getSequenceType(), 128 | ]; 129 | } 130 | 131 | /** 132 | * @param array $data 133 | * @return ResponseInterface|FetchPaymentMethodsResponse 134 | */ 135 | public function sendData($data) 136 | { 137 | $query = http_build_query($data); 138 | $response = $this->sendRequest(self::GET, '/methods' . ($query ? '?' . $query : '')); 139 | 140 | return $this->response = new FetchPaymentMethodsResponse($this, $response); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/Message/Request/FetchTransactionRequest.php: -------------------------------------------------------------------------------- 1 | validate('apiKey', 'transactionReference'); 24 | 25 | $data = []; 26 | $data['id'] = $this->getTransactionReference(); 27 | 28 | return $data; 29 | } 30 | 31 | /** 32 | * @param array $data 33 | * @return ResponseInterface|FetchTransactionResponse 34 | */ 35 | public function sendData($data) 36 | { 37 | $response = $this->sendRequest(self::GET, '/payments/' . $data['id']); 38 | 39 | return $this->response = new FetchTransactionResponse($this, $response); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Message/Request/PurchaseRequest.php: -------------------------------------------------------------------------------- 1 | getParameter('metadata'); 23 | } 24 | 25 | /** 26 | * @param array $value 27 | * @return $this 28 | */ 29 | public function setMetadata(array $value) 30 | { 31 | return $this->setParameter('metadata', $value); 32 | } 33 | 34 | /** 35 | * @return string 36 | */ 37 | public function getLocale() 38 | { 39 | return $this->getParameter('locale'); 40 | } 41 | 42 | /** 43 | * @param string $value 44 | * @return $this 45 | */ 46 | public function setLocale($value) 47 | { 48 | return $this->setParameter('locale', $value); 49 | } 50 | 51 | /** 52 | * @return string 53 | */ 54 | public function getBillingEmail() 55 | { 56 | return $this->getParameter('billingEmail'); 57 | } 58 | 59 | /** 60 | * @param string $value 61 | * @return $this 62 | */ 63 | public function setBillingEmail($value) 64 | { 65 | return $this->setParameter('billingEmail', $value); 66 | } 67 | 68 | /** 69 | * @return string 70 | */ 71 | public function getCustomerReference() 72 | { 73 | return $this->getParameter('customerReference'); 74 | } 75 | 76 | /** 77 | * @param string $value 78 | * @return $this 79 | */ 80 | public function setCustomerReference($value) 81 | { 82 | return $this->setParameter('customerReference', $value); 83 | } 84 | 85 | /** 86 | * @return string 87 | */ 88 | public function getMandateId() 89 | { 90 | return $this->getParameter('mandateId'); 91 | } 92 | 93 | /** 94 | * @param string $value 95 | * @return $this 96 | */ 97 | public function setMandateId($value) 98 | { 99 | return $this->setParameter('mandateId', $value); 100 | } 101 | 102 | /** 103 | * @return string 104 | */ 105 | public function getSequenceType() 106 | { 107 | return $this->getParameter('sequenceType'); 108 | } 109 | 110 | /** 111 | * @param string $value 112 | * @return $this 113 | */ 114 | public function setSequenceType($value) 115 | { 116 | return $this->setParameter('sequenceType', $value); 117 | } 118 | 119 | /** 120 | * @return string 121 | */ 122 | public function getCardToken() 123 | { 124 | return $this->getParameter('cardToken'); 125 | } 126 | 127 | /** 128 | * @param string $value 129 | * @return $this 130 | */ 131 | public function setCardToken($value) 132 | { 133 | return $this->setParameter('cardToken', $value); 134 | } 135 | 136 | /** 137 | * @return string 138 | */ 139 | public function getInclude() 140 | { 141 | return $this->getParameter('include'); 142 | } 143 | 144 | /** 145 | * @param string $value 146 | * @return $this 147 | */ 148 | public function setInclude($value) 149 | { 150 | return $this->setParameter('include', $value); 151 | } 152 | 153 | 154 | /** 155 | * @return array 156 | * @throws InvalidRequestException 157 | */ 158 | public function getData() 159 | { 160 | $this->validate('apiKey', 'amount', 'currency', 'description', 'returnUrl'); 161 | 162 | $data = []; 163 | $data['amount'] = [ 164 | "value" => $this->getAmount(), 165 | "currency" => $this->getCurrency() 166 | ]; 167 | $data['description'] = $this->getDescription(); 168 | $data['redirectUrl'] = $this->getReturnUrl(); 169 | $data['method'] = $this->getPaymentMethod(); 170 | $data['metadata'] = $this->getMetadata(); 171 | 172 | if ($this->getTransactionId()) { 173 | $data['metadata']['transactionId'] = $this->getTransactionId(); 174 | } 175 | 176 | if ($issuer = $this->getIssuer()) { 177 | $data['issuer'] = $issuer; 178 | } 179 | 180 | $webhookUrl = $this->getNotifyUrl(); 181 | if (null !== $webhookUrl) { 182 | $data['webhookUrl'] = $webhookUrl; 183 | } 184 | 185 | if ($locale = $this->getLocale()) { 186 | $data['locale'] = $locale; 187 | } 188 | 189 | if ($billingEmail = $this->getBillingEmail()) { 190 | $data['billingEmail'] = $billingEmail; 191 | } 192 | 193 | if ($customerReference = $this->getCustomerReference()) { 194 | $data['customerId'] = $customerReference; 195 | } 196 | 197 | if ($sequenceType = $this->getSequenceType()) { 198 | $data['sequenceType'] = $sequenceType; 199 | } 200 | 201 | if ($mandateId = $this->getMandateId()) { 202 | $data['mandateId'] = $mandateId; 203 | } 204 | 205 | if ($cardToken = $this->getCardToken()) { 206 | $data['cardToken'] = $cardToken; 207 | } 208 | 209 | return $data; 210 | } 211 | 212 | /** 213 | * @param array $data 214 | * @return ResponseInterface|PurchaseResponse 215 | */ 216 | public function sendData($data) 217 | { 218 | $endpoint = '/payments'; 219 | 220 | if ($include = $this->getInclude()) { 221 | $endpoint .= '?include=' . $include; 222 | } 223 | 224 | $response = $this->sendRequest(self::POST, $endpoint, $data); 225 | 226 | return $this->response = new PurchaseResponse($this, $response); 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /src/Message/Request/RefundRequest.php: -------------------------------------------------------------------------------- 1 | validate('apiKey', 'transactionReference', 'amount', 'currency'); 27 | 28 | $data = []; 29 | 30 | $data['amount'] = [ 31 | "value" => $this->getAmount(), 32 | "currency" => $this->getCurrency() 33 | ]; 34 | 35 | if (is_string($this->getParameter('description'))) { 36 | $data['description'] = $this->getParameter('description'); 37 | } 38 | 39 | return $data; 40 | } 41 | 42 | /** 43 | * @param array $data 44 | * @return ResponseInterface|RefundResponse 45 | */ 46 | public function sendData($data) 47 | { 48 | $response = $this->sendRequest( 49 | self::POST, 50 | '/payments/' . $this->getTransactionReference() . '/refunds', 51 | $data 52 | ); 53 | 54 | return $this->response = new RefundResponse($this, $response); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Message/Request/RevokeCustomerMandateRequest.php: -------------------------------------------------------------------------------- 1 | getParameter('customerReference'); 23 | } 24 | 25 | /** 26 | * @param string $value 27 | * @return AbstractRequest 28 | */ 29 | public function setCustomerReference($value) 30 | { 31 | return $this->setParameter('customerReference', $value); 32 | } 33 | 34 | /** 35 | * @return string 36 | */ 37 | public function getMandateId() 38 | { 39 | return $this->getParameter('mandateId'); 40 | } 41 | 42 | /** 43 | * @param string $value 44 | * @return AbstractRequest 45 | */ 46 | public function setMandateId($value) 47 | { 48 | return $this->setParameter('mandateId', $value); 49 | } 50 | 51 | /** 52 | * @return array 53 | * @throws InvalidRequestException 54 | */ 55 | public function getData() 56 | { 57 | $this->validate('apiKey', 'customerReference', 'mandateId'); 58 | 59 | $data['customerReference'] = $this->getCustomerReference(); 60 | $data['mandateId'] = $this->getMandateId(); 61 | 62 | return $data; 63 | } 64 | 65 | /** 66 | * @param array $data 67 | * @return RevokeCustomerMandateResponse 68 | */ 69 | public function sendData($data) 70 | { 71 | $response = $this->sendRequest( 72 | self::DELETE, 73 | "/customers/{$this->getCustomerReference()}/mandates/{$this->getMandateId()}" 74 | ); 75 | 76 | return $this->response = new RevokeCustomerMandateResponse($this, $response); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Message/Request/UpdateCustomerRequest.php: -------------------------------------------------------------------------------- 1 | getParameter('customerReference'); 25 | } 26 | 27 | /** 28 | * @param string $value 29 | * @return AbstractRequest 30 | */ 31 | public function setCustomerReference($value) 32 | { 33 | return $this->setParameter('customerReference', $value); 34 | } 35 | 36 | /** 37 | * Get the customer's email address. 38 | * 39 | * @return string 40 | */ 41 | public function getEmail() 42 | { 43 | return $this->getParameter('email'); 44 | } 45 | 46 | /** 47 | * @param string $value 48 | * @return AbstractRequest 49 | */ 50 | public function setEmail($value) 51 | { 52 | return $this->setParameter('email', $value); 53 | } 54 | 55 | /** 56 | * Get the customer's locale. 57 | * 58 | * Possible values: de_DE, en_US, es_ES, fr_FR, nl_BE, fr_BE, nl_NL. 59 | * 60 | * @return string 61 | */ 62 | public function getLocale() 63 | { 64 | return $this->getParameter('locale'); 65 | } 66 | 67 | /** 68 | * Optional value. 69 | * 70 | * @param string $value 71 | * @return AbstractRequest 72 | */ 73 | public function setLocale($value) 74 | { 75 | return $this->setParameter('locale', $value); 76 | } 77 | 78 | /** 79 | * Get the customer's metadata. 80 | * 81 | * @return array 82 | */ 83 | public function getMetadata() 84 | { 85 | return $this->getParameter('metadata'); 86 | } 87 | 88 | /** 89 | * Optional value. 90 | * 91 | * @param array $value 92 | * @return AbstractRequest 93 | */ 94 | public function setMetadata($value) 95 | { 96 | return $this->setParameter('metadata', $value); 97 | } 98 | 99 | /** 100 | * @return array 101 | * @throws InvalidRequestException 102 | */ 103 | public function getData() 104 | { 105 | $this->validate('apiKey', 'customerReference'); 106 | 107 | $data = []; 108 | $data['name'] = $this->getDescription(); 109 | $data['email'] = $this->getEmail(); 110 | $data['locale'] = $this->getLocale(); 111 | 112 | if ($this->getMetadata()) { 113 | $data['metadata'] = $this->getMetadata(); 114 | } 115 | 116 | return $data; 117 | } 118 | 119 | /** 120 | * @param array $data 121 | * @return UpdateCustomerResponse 122 | */ 123 | public function sendData($data) 124 | { 125 | $response = $this->sendRequest(self::POST, '/customers/' . $this->getCustomerReference(), $data); 126 | 127 | return $this->response = new UpdateCustomerResponse($this, $response); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/Message/Response/AbstractMollieResponse.php: -------------------------------------------------------------------------------- 1 | data['status']) && isset($this->data['detail'])) { 15 | return false; 16 | } 17 | 18 | return true; 19 | } 20 | 21 | /** 22 | * @return string 23 | */ 24 | public function getMessage() 25 | { 26 | return json_encode($this->data); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Message/Response/CancelOrderResponse.php: -------------------------------------------------------------------------------- 1 | data['status'])) { 16 | return false; 17 | } 18 | 19 | return 'canceled' === $this->data['status']; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Message/Response/CompleteOrderResponse.php: -------------------------------------------------------------------------------- 1 | isPaid(); 16 | } 17 | 18 | /** 19 | * The order status is never a redirect 20 | * 21 | * {@inheritdoc} 22 | */ 23 | public function isRedirect() 24 | { 25 | return false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Message/Response/CompletePurchaseResponse.php: -------------------------------------------------------------------------------- 1 | isPaid(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Message/Response/CreateCustomerMandateResponse.php: -------------------------------------------------------------------------------- 1 | data['id'])) { 16 | return $this->data['id']; 17 | } 18 | } 19 | 20 | /** 21 | * @return bool 22 | */ 23 | public function isSuccessful() 24 | { 25 | return isset($this->data['id']); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Message/Response/CreateCustomerResponse.php: -------------------------------------------------------------------------------- 1 | data['id'])) { 16 | return $this->data['id']; 17 | } 18 | 19 | return null; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Message/Response/CreateOrderResponse.php: -------------------------------------------------------------------------------- 1 | data['_embedded']['mandates'])) { 13 | return $this->data['_embedded']['mandates']; 14 | } 15 | } 16 | 17 | public function hasValidMandates() 18 | { 19 | if ($mandates = $this->getMandates()) { 20 | foreach ($mandates as $mandate) { 21 | if ($mandate['status'] == "valid") { 22 | return true; 23 | } 24 | } 25 | } 26 | 27 | return false; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Message/Response/FetchCustomerResponse.php: -------------------------------------------------------------------------------- 1 | data['id'])) { 16 | return $this->data['id']; 17 | } 18 | 19 | return null; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Message/Response/FetchIssuersResponse.php: -------------------------------------------------------------------------------- 1 | data['issuers']) === false) { 21 | return []; 22 | } 23 | 24 | $issuers = []; 25 | foreach ($this->data['issuers'] as $issuer) { 26 | $issuers[] = new Issuer($issuer['id'], $issuer['name'], $this->data['id']); 27 | } 28 | 29 | return $issuers; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Message/Response/FetchOrderResponse.php: -------------------------------------------------------------------------------- 1 | data['lines'])) { 16 | return $this->data['lines']; 17 | } 18 | 19 | return null; 20 | } 21 | 22 | public function getItems() 23 | { 24 | 25 | if (isset($this->data['lines'])) { 26 | $items = []; 27 | 28 | foreach ($this->data['lines'] as $line) { 29 | $items[] = new Item($line); 30 | } 31 | 32 | return new ItemBag($items); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Message/Response/FetchPaymentMethodsResponse.php: -------------------------------------------------------------------------------- 1 | data['_embedded']["methods"]) === false) { 21 | return []; 22 | } 23 | 24 | $paymentMethods = []; 25 | foreach ($this->data['_embedded']["methods"] as $method) { 26 | $paymentMethods[] = new PaymentMethod($method['id'], $method['description']); 27 | } 28 | 29 | return $paymentMethods; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Message/Response/FetchTransactionResponse.php: -------------------------------------------------------------------------------- 1 | data['_links']['checkout']['href']); 26 | } 27 | 28 | /** 29 | * {@inheritdoc} 30 | */ 31 | public function getRedirectUrl() 32 | { 33 | if ($this->isRedirect()) { 34 | return $this->data['_links']['checkout']['href']; 35 | } 36 | 37 | return null; 38 | } 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | public function getRedirectData() 44 | { 45 | return null; 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function isSuccessful() 52 | { 53 | return parent::isSuccessful(); 54 | } 55 | 56 | /** 57 | * @return boolean 58 | */ 59 | public function isOpen() 60 | { 61 | return isset($this->data['status']) 62 | && ('open' === $this->data['status'] || 'created' === $this->data['status']); 63 | } 64 | 65 | /** 66 | * @return boolean 67 | */ 68 | public function isCancelled() 69 | { 70 | return isset($this->data['status']) && 'canceled' === $this->data['status']; 71 | } 72 | 73 | /** 74 | * @return boolean 75 | */ 76 | public function isPaid() 77 | { 78 | return isset($this->data['status']) && 'paid' === $this->data['status']; 79 | } 80 | 81 | /** 82 | * @return boolean 83 | */ 84 | public function isAuthorized() 85 | { 86 | return isset($this->data['status']) && 'authorized' === $this->data['status']; 87 | } 88 | 89 | /** 90 | * @return boolean 91 | */ 92 | public function isPaidOut() 93 | { 94 | return isset($this->data['_links']['settlement']); 95 | } 96 | 97 | /** 98 | * @return boolean 99 | */ 100 | public function isExpired() 101 | { 102 | return isset($this->data['status']) && 'expired' === $this->data['status']; 103 | } 104 | 105 | public function isRefunded() 106 | { 107 | return isset($this->data['_links']['refunds']); 108 | } 109 | 110 | public function isPartialRefunded() 111 | { 112 | return $this->isRefunded() 113 | && isset($this->data['amountRemaining']) 114 | && $this->data['amountRemaining']['value'] > 0; 115 | } 116 | 117 | /** 118 | * @return boolean 119 | */ 120 | public function hasChargebacks() 121 | { 122 | return !empty($this->data['_links']['chargebacks']); 123 | } 124 | 125 | /** 126 | * @return string|null 127 | */ 128 | public function getTransactionReference() 129 | { 130 | if (isset($this->data['id'])) { 131 | return $this->data['id']; 132 | } 133 | 134 | return null; 135 | } 136 | 137 | /** 138 | * @return string|null 139 | */ 140 | public function getTransactionId() 141 | { 142 | if (isset($this->data['metadata']['transactionId'])) { 143 | return $this->data['metadata']['transactionId']; 144 | } 145 | 146 | return null; 147 | } 148 | 149 | /** 150 | * @return string|null 151 | */ 152 | public function getStatus() 153 | { 154 | if (isset($this->data['status'])) { 155 | return $this->data['status']; 156 | } 157 | 158 | return null; 159 | } 160 | 161 | /** 162 | * @return string|null 163 | */ 164 | public function getAmount() 165 | { 166 | if (isset($this->data['amount']) && is_array($this->data['amount'])) { 167 | /** 168 | * $this->data['amount'] = [ 169 | * "currency" => "EUR", 170 | * "value" => "50", 171 | * ] 172 | */ 173 | return $this->data['amount']['value']; 174 | } 175 | 176 | return null; 177 | } 178 | 179 | public function getCurrency() 180 | { 181 | if ($this->isSuccessful() && is_array($this->data['amount'])) { 182 | /** 183 | * $this->data['amount'] = [ 184 | * "currency" => "EUR", 185 | * "value" => "50", 186 | * ] 187 | */ 188 | return $this->data['amount']['currency']; 189 | } 190 | 191 | return null; 192 | } 193 | 194 | /** 195 | * @return array|null 196 | */ 197 | public function getMetadata() 198 | { 199 | if (isset($this->data['metadata'])) { 200 | return $this->data['metadata']; 201 | } 202 | 203 | return null; 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /src/Message/Response/PurchaseResponse.php: -------------------------------------------------------------------------------- 1 | data['paymentId']; 16 | } 17 | 18 | /** 19 | * @return string 20 | */ 21 | public function getTransactionId() 22 | { 23 | return $this->data['id']; 24 | } 25 | 26 | /** 27 | * @return bool 28 | */ 29 | public function isSuccessful() 30 | { 31 | return isset($this->data['id']); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Message/Response/RevokeCustomerMandateResponse.php: -------------------------------------------------------------------------------- 1 | data['id'])) { 16 | return $this->data['id']; 17 | } 18 | 19 | return null; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/GatewayTest.php: -------------------------------------------------------------------------------- 1 | gateway = new Gateway(); 37 | } 38 | 39 | public function testFetchIssuers() 40 | { 41 | $request = $this->gateway->fetchIssuers(); 42 | 43 | $this->assertInstanceOf(FetchIssuersRequest::class, $request); 44 | } 45 | 46 | public function testFetchPaymentMethods() 47 | { 48 | $request = $this->gateway->fetchPaymentMethods(); 49 | 50 | $this->assertInstanceOf(FetchPaymentMethodsRequest::class, $request); 51 | } 52 | 53 | /** 54 | * @throws InvalidRequestException 55 | */ 56 | public function testPurchase() 57 | { 58 | $request = $this->gateway->purchase(array('amount' => '10.00', 'currency' => 'EUR')); 59 | 60 | $this->assertInstanceOf(PurchaseRequest::class, $request); 61 | $this->assertSame('10.00', $request->getAmount()); 62 | $this->assertSame('EUR', $request->getCurrency()); 63 | } 64 | 65 | /** 66 | * @throws InvalidRequestException 67 | */ 68 | public function testPurchaseReturn() 69 | { 70 | $request = $this->gateway->completePurchase(array('amount' => '10.00', 'currency' => 'EUR')); 71 | 72 | $this->assertInstanceOf(CompletePurchaseRequest::class, $request); 73 | $this->assertSame('10.00', $request->getAmount()); 74 | $this->assertSame('EUR', $request->getCurrency()); 75 | } 76 | 77 | public function testRefund() 78 | { 79 | $request = $this->gateway->refund( 80 | array( 81 | 'apiKey' => 'key', 82 | 'transactionReference' => 'tr_Qzin4iTWrU', 83 | 'amount' => '10.00', 84 | 'currency' => 'EUR' 85 | ) 86 | ); 87 | 88 | $this->assertInstanceOf(RefundRequest::class, $request); 89 | $data = $request->getData(); 90 | $this->assertSame( 91 | [ 92 | 'value' => '10.00', 93 | 'currency' => 'EUR' 94 | ], 95 | $data['amount'] 96 | ); 97 | } 98 | 99 | public function testThatRefundDoesntWorkWithoutAmount() 100 | { 101 | $this->expectException(\Omnipay\Common\Exception\InvalidRequestException::class); 102 | 103 | $request = $this->gateway->refund( 104 | array( 105 | 'apiKey' => 'key', 106 | 'transactionReference' => 'tr_Qzin4iTWrU' 107 | ) 108 | ); 109 | 110 | $this->assertInstanceOf(RefundRequest::class, $request); 111 | $request->getData(); 112 | } 113 | 114 | public function testFetchTransaction() 115 | { 116 | $request = $this->gateway->fetchTransaction( 117 | array( 118 | 'apiKey' => 'key', 119 | 'transactionReference' => 'tr_Qzin4iTWrU', 120 | ) 121 | ); 122 | 123 | $this->assertInstanceOf(FetchTransactionRequest::class, $request); 124 | 125 | $data = $request->getData(); 126 | $this->assertSame('tr_Qzin4iTWrU', $data['id']); 127 | } 128 | 129 | public function testCreateCustomer() 130 | { 131 | $request = $this->gateway->createCustomer( 132 | array( 133 | 'description' => 'Test name', 134 | 'email' => 'test@example.com', 135 | 'metadata' => 'Something something something dark side.', 136 | 'locale' => 'nl_NL', 137 | ) 138 | ); 139 | 140 | $this->assertInstanceOf(CreateCustomerRequest::class, $request); 141 | } 142 | 143 | public function testUpdateCustomer() 144 | { 145 | $request = $this->gateway->updateCustomer( 146 | array( 147 | 'apiKey' => 'key', 148 | 'customerReference' => 'cst_bSNBBJBzdG', 149 | 'description' => 'Test name2', 150 | 'email' => 'test@example.com', 151 | 'metadata' => 'Something something something dark side.', 152 | 'locale' => 'nl_NL', 153 | ) 154 | ); 155 | 156 | $this->assertInstanceOf(UpdateCustomerRequest::class, $request); 157 | 158 | $data = $request->getData(); 159 | 160 | $this->assertSame('Test name2', $data['name']); 161 | } 162 | 163 | public function testFetchCustomer() 164 | { 165 | $request = $this->gateway->fetchCustomer( 166 | array( 167 | 'apiKey' => 'key', 168 | 'customerReference' => 'cst_bSNBBJBzdG', 169 | ) 170 | ); 171 | 172 | $this->assertInstanceOf(FetchCustomerRequest::class, $request); 173 | } 174 | 175 | public function testFetchCustomerMandates() 176 | { 177 | $request = $this->gateway->fetchCustomerMandates( 178 | array( 179 | 'apiKey' => 'key', 180 | 'customerReference' => 'cst_bSNBBJBzdG', 181 | ) 182 | ); 183 | 184 | $this->assertInstanceOf(FetchCustomerMandatesRequest::class, $request); 185 | } 186 | 187 | public function testRevokeCustomerMandate() 188 | { 189 | $request = $this->gateway->revokeCustomerMandate( 190 | array( 191 | 'apiKey' => "key", 192 | "customerReference" => "cst_bSNBBJBzdG", 193 | "mandateId" => "mdt_pWUnw6pkBN", 194 | ) 195 | ); 196 | 197 | $this->assertInstanceOf(RevokeCustomerMandateRequest::class, $request); 198 | } 199 | 200 | public function testCreateCustomerMandate() 201 | { 202 | $request = $this->gateway->createCustomerMandate( 203 | array( 204 | 'apiKey' => "mykey", 205 | 'consumerName' => "Customer A", 206 | 'consumerAccount' => "NL53INGB0000000000", 207 | "method" => "directdebit", 208 | 'customerReference' => 'cst_bSNBBJBzdG', 209 | 'mandateReference' => "YOUR-COMPANY-MD13804", 210 | ) 211 | ); 212 | 213 | $this->assertInstanceOf(CreateCustomerMandateRequest::class, $request); 214 | } 215 | 216 | public function testVoid() 217 | { 218 | $this->assertInstanceOf(CancelOrderRequest::class, $this->gateway->void()); 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /tests/Message/AbstractMollieRequestTest.php: -------------------------------------------------------------------------------- 1 | gateway = new Gateway($this->getHttpClient()); 23 | } 24 | 25 | 26 | public function testVersionString() 27 | { 28 | $request = $this->gateway->fetchIssuers(); 29 | $request->send(); 30 | 31 | /** @var \Psr\Http\Message\RequestInterface $httpRequest */ 32 | $httpRequest = $this->getMockedRequests()[0]; 33 | 34 | $versionString = 'Omnipay-Mollie/'.Gateway::GATEWAY_VERSION.' PHP/' . phpversion(); 35 | $this->assertEquals($versionString, $httpRequest->getHeaderLine('User-Agent')); 36 | } 37 | 38 | public function testCustomVersionStrings() 39 | { 40 | $this->gateway->initialize([ 41 | 'versionStrings' => ['Acme/6.84'] 42 | ]); 43 | $request = $this->gateway->fetchIssuers(); 44 | $request->send(); 45 | 46 | /** @var \Psr\Http\Message\RequestInterface $httpRequest */ 47 | $httpRequest = $this->getMockedRequests()[0]; 48 | 49 | $versionString = 'Omnipay-Mollie/'.Gateway::GATEWAY_VERSION.' PHP/' . phpversion() . ' Acme/6.84'; 50 | $this->assertEquals($versionString, $httpRequest->getHeaderLine('User-Agent')); 51 | } 52 | 53 | public function testAddVersionString() 54 | { 55 | $this->gateway->addVersionString('Acme/6.84'); 56 | $request = $this->gateway->fetchIssuers(); 57 | $request->send(); 58 | 59 | /** @var \Psr\Http\Message\RequestInterface $httpRequest */ 60 | $httpRequest = $this->getMockedRequests()[0]; 61 | 62 | $versionString = 'Omnipay-Mollie/'.Gateway::GATEWAY_VERSION.' PHP/' . phpversion() . ' Acme/6.84'; 63 | $this->assertEquals($versionString, $httpRequest->getHeaderLine('User-Agent')); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/Message/AssertRequestTrait.php: -------------------------------------------------------------------------------- 1 | assertEquals($expectedRequest->getMethod(), $actualRequest->getMethod(), "Expected request Method should be equal to actual request method."); 10 | 11 | $this->assertEquals($expectedRequest->getUri(), $actualRequest->getUri(), "Expected request Uri should be equal to actual request body."); 12 | 13 | if(!empty((string) $expectedRequest->getBody())) { 14 | $this->assertJsonStringEqualsJsonString((string) $expectedRequest->getBody(), (string) $actualRequest->getBody(), "Expected request Body should be equal to actual request body."); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /tests/Message/CancelOrderRequestTest.php: -------------------------------------------------------------------------------- 1 | httpClient = $this->createMock(ClientInterface::class); 26 | $this->request = new CancelOrderRequest($this->httpClient, $this->getHttpRequest()); 27 | } 28 | 29 | public function insufficientDataProvider() 30 | { 31 | return [ 32 | [['apiKey' => 'mykey']], 33 | [['transactionReference' => 'myref']], 34 | ]; 35 | } 36 | 37 | public function responseDataProvider() 38 | { 39 | return [ 40 | [['id' => 'ord_kEn1PlbGa'], false], 41 | [['status' => 'paid', 'id' => 'ord_kEn1PlbGa'], false], 42 | [['status' => 'canceled', 'id' => 'ord_kEn1PlbGa'], true], 43 | ]; 44 | } 45 | 46 | /** 47 | * @dataProvider insufficientDataProvider 48 | * 49 | * @param array $input 50 | */ 51 | public function testGetDataWillValidateRequiredData(array $input) 52 | { 53 | $this->expectException(\Omnipay\Common\Exception\InvalidRequestException::class); 54 | $this->request->initialize($input); 55 | $this->request->getData(); 56 | } 57 | 58 | public function testGetDataWillReturnEmptyArray() 59 | { 60 | $this->request->initialize(['apiKey' => 'mykey', 'transactionReference' => 'myref']); 61 | self::assertEquals([], $this->request->getData()); 62 | } 63 | 64 | /** 65 | * @dataProvider responseDataProvider 66 | */ 67 | public function testSendData(array $responseData, $success) 68 | { 69 | $response = $this->createMock(ResponseInterface::class); 70 | $response->expects(self::once()) 71 | ->method('getBody') 72 | ->willReturn(\json_encode($responseData)); 73 | 74 | $this->httpClient->expects(self::once()) 75 | ->method('request') 76 | ->with( 77 | 'DELETE', 78 | 'https://api.mollie.com/v2/orders/ord_kEn1PlbGa', 79 | $this->callback(function ($headers) { 80 | return $headers['Authorization'] == 'Bearer mykey'; 81 | }) 82 | )->willReturn($response); 83 | 84 | $this->request->initialize(['apiKey' => 'mykey', 'transactionReference' => 'ord_kEn1PlbGa']); 85 | $voidResponse = $this->request->sendData([]); 86 | 87 | $this->assertInstanceOf(CancelOrderResponse::class, $voidResponse); 88 | $this->assertEquals($success, $voidResponse->isSuccessful()); 89 | $this->assertSame('ord_kEn1PlbGa', $voidResponse->getTransactionReference()); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /tests/Message/CompleteOrderRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new CompleteOrderRequest($this->getHttpClient(), $this->getHttpRequest()); 24 | $this->request->initialize(array( 25 | 'apiKey' => 'mykey', 26 | )); 27 | 28 | $this->getHttpRequest()->request->replace(array( 29 | 'id' => 'ord_kEn1PlbGa', 30 | )); 31 | } 32 | 33 | public function testGetDataWithoutIDParameter() 34 | { 35 | $this->expectException(\Omnipay\Common\Exception\InvalidRequestException::class); 36 | $this->expectExceptionMessage('The transactionReference parameter is required'); 37 | $this->getHttpRequest()->request->remove('id'); 38 | 39 | $data = $this->request->getData(); 40 | 41 | $this->assertEmpty($data); 42 | } 43 | 44 | /** 45 | * @throws \Omnipay\Common\Exception\InvalidRequestException 46 | */ 47 | public function testGetData() 48 | { 49 | $data = $this->request->getData(); 50 | 51 | $this->assertSame("ord_kEn1PlbGa", $data['id']); 52 | $this->assertCount(1, $data); 53 | } 54 | 55 | public function testSendSuccess() 56 | { 57 | $this->setMockHttpResponse('CompleteOrderSuccess.txt'); 58 | /** @var CompleteOrderResponse $response */ 59 | $response = $this->request->send(); 60 | 61 | $this->assertEqualRequest(new Request("GET", "https://api.mollie.com/v2/orders/ord_kEn1PlbGa"), $this->getMockClient()->getLastRequest()); 62 | 63 | $this->assertInstanceOf(CompleteOrderResponse::class, $response); 64 | $this->assertFalse($response->isSuccessful()); 65 | $this->assertTrue($response->isOpen()); 66 | $this->assertFalse($response->isPaid()); 67 | $this->assertFalse($response->isRedirect()); 68 | $this->assertSame('ord_kEn1PlbGa', $response->getTransactionReference()); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /tests/Message/CompletePurchaseRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new CompletePurchaseRequest($this->getHttpClient(), $this->getHttpRequest()); 22 | $this->request->initialize(array( 23 | 'apiKey' => 'mykey', 24 | )); 25 | 26 | $this->getHttpRequest()->request->replace(array( 27 | 'id' => 'tr_Qzin4iTWrU', 28 | )); 29 | } 30 | 31 | public function testGetDataWithoutIDParameter() 32 | { 33 | $this->expectException(\Omnipay\Common\Exception\InvalidRequestException::class); 34 | $this->expectExceptionMessage('The transactionReference parameter is required'); 35 | 36 | $this->getHttpRequest()->request->remove('id'); 37 | 38 | $data = $this->request->getData(); 39 | 40 | $this->assertEmpty($data); 41 | } 42 | 43 | /** 44 | * @throws \Omnipay\Common\Exception\InvalidRequestException 45 | */ 46 | public function testGetData() 47 | { 48 | $data = $this->request->getData(); 49 | 50 | $this->assertSame("tr_Qzin4iTWrU", $data['id']); 51 | $this->assertCount(1, $data); 52 | } 53 | 54 | public function testSendSuccess() 55 | { 56 | $this->setMockHttpResponse('CompletePurchaseSuccess.txt'); 57 | $response = $this->request->send(); 58 | 59 | $this->assertEqualRequest(new Request("GET", "https://api.mollie.com/v2/payments/tr_Qzin4iTWrU"), $this->getMockClient()->getLastRequest()); 60 | 61 | $this->assertInstanceOf(CompletePurchaseResponse::class, $response); 62 | $this->assertTrue($response->isSuccessful()); 63 | $this->assertFalse($response->isOpen()); 64 | $this->assertTrue($response->isPaid()); 65 | $this->assertFalse($response->isRedirect()); 66 | $this->assertSame('tr_Qzin4iTWrU', $response->getTransactionReference()); 67 | } 68 | 69 | public function testSendExpired() 70 | { 71 | $this->setMockHttpResponse('CompletePurchaseExpired.txt'); 72 | $response = $this->request->send(); 73 | 74 | $this->assertEqualRequest(new Request("GET", "https://api.mollie.com/v2/payments/tr_Qzin4iTWrU"), $this->getMockClient()->getLastRequest()); 75 | 76 | $this->assertInstanceOf(CompletePurchaseResponse::class, $response); 77 | $this->assertFalse($response->isSuccessful()); 78 | $this->assertFalse($response->isPaid()); 79 | $this->assertTrue($response->isExpired()); 80 | $this->assertFalse($response->isRedirect()); 81 | $this->assertSame('tr_Qzin4iTWrU', $response->getTransactionReference()); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /tests/Message/CreateCustomerMandateRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new CreateCustomerMandateRequest($this->getHttpClient(), $this->getHttpRequest()); 23 | 24 | $this->request->initialize(array( 25 | 'apiKey' => "mykey", 26 | 'consumerName' => "Customer A", 27 | 'consumerAccount' => "NL53INGB0000000000", 28 | "method" => "directdebit", 29 | 'customerReference' => 'cst_bSNBBJBzdG', 30 | 'mandateReference' => "YOUR-COMPANY-MD13804" 31 | )); 32 | } 33 | 34 | /** 35 | * @throws InvalidRequestException 36 | */ 37 | public function testGetData() 38 | { 39 | $data = $this->request->getData(); 40 | 41 | $this->assertSame("NL53INGB0000000000", $data['consumerAccount']); 42 | $this->assertSame('directdebit', $data['method']); 43 | $this->assertSame("YOUR-COMPANY-MD13804", $data['mandateReference']); 44 | 45 | $this->assertCount(4, $data); 46 | } 47 | 48 | public function testSendSuccess() 49 | { 50 | $this->setMockHttpResponse('CreateCustomerMandateSuccess.txt'); 51 | 52 | /** @var CreateCustomerMandateResponse $response */ 53 | $response = $this->request->send(); 54 | 55 | $this->assertEqualRequest(new Request("POST", "https://api.mollie.com/v2/customers/cst_bSNBBJBzdG/mandates"), $this->getMockClient()->getLastRequest()); 56 | 57 | $this->assertInstanceOf(CreateCustomerMandateResponse::class, $response); 58 | $this->assertSame("mdt_h3gAaD5zP", $response->getMandateId()); 59 | 60 | $this->assertTrue($response->isSuccessful()); 61 | $this->assertJsonStringEqualsJsonString( 62 | '{"resource":"mandate","id":"mdt_h3gAaD5zP","mode":"test","status":"valid","method":"directdebit","details":{"consumerName":"John Doe","consumerAccount":"NL55INGB0000000000","consumerBic":"INGBNL2A"},"mandateReference":"YOUR-COMPANY-MD13804","signatureDate":"2018-05-07","createdAt":"2018-05-07T10:49:08+00:00","_links":{"self":{"href":"https:\/\/api.mollie.com\/v2\/customers\/cst_4qqhO89gsT\/mandates\/mdt_h3gAaD5zP","type":"application\/hal+json"},"customer":{"href":"https:\/\/api.mollie.com\/v2\/customers\/cst_4qqhO89gsT","type":"application\/hal+json"},"documentation":{"href":"https:\/\/docs.mollie.com\/reference\/v2\/mandates-api\/create-mandate","type":"text\/html"}}}', 63 | $response->getMessage() 64 | ); 65 | } 66 | 67 | public function testSendFailure() 68 | { 69 | $this->setMockHttpResponse('CreateCustomerMandateFailure.txt'); 70 | $response = $this->request->send(); 71 | 72 | $this->assertFalse($response->isSuccessful()); 73 | $this->assertFalse($response->isRedirect()); 74 | $this->assertNull($response->getTransactionReference()); 75 | $this->assertJsonStringEqualsJsonString( 76 | '{"status":401,"title":"Unauthorized Request","detail":"Missing authentication, or failed to authenticate","_links":{"documentation":{"href":"https:\/\/docs.mollie.com\/guides\/authentication","type":"text\/html"}}}', 77 | $response->getMessage() 78 | ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /tests/Message/CreateCustomerRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new CreateCustomerRequest($this->getHttpClient(), $this->getHttpRequest()); 24 | 25 | $this->request->initialize(array( 26 | 'apiKey' => 'mykey', 27 | 'description' => 'John Doe', 28 | 'email' => 'john@doe.com', 29 | 'locale' => 'nl_NL', 30 | 'metadata' => 'Just some meta data.', 31 | )); 32 | } 33 | 34 | /** 35 | * @throws InvalidRequestException 36 | */ 37 | public function testData() 38 | { 39 | $this->request->initialize(array( 40 | 'apiKey' => 'mykey', 41 | 'description' => 'John Doe', 42 | 'email' => 'john@doe.com', 43 | 'metadata' => 'Just some meta data.', 44 | )); 45 | $data = $this->request->getData(); 46 | 47 | $this->assertSame("John Doe", $data['name']); 48 | $this->assertSame('john@doe.com', $data['email']); 49 | $this->assertSame('Just some meta data.', $data['metadata']); 50 | $this->assertCount(4, $data); 51 | } 52 | 53 | public function testSendSuccess() 54 | { 55 | $this->setMockHttpResponse('CreateCustomerSuccess.txt'); 56 | 57 | /** @var CreateCustomerResponse $response */ 58 | $response = $this->request->send(); 59 | 60 | $this->assertEqualRequest( 61 | new Request( 62 | "POST", 63 | "https://api.mollie.com/v2/customers", 64 | [], 65 | '{ 66 | "name":"John Doe", 67 | "email":"john@doe.com", 68 | "metadata":"Just some meta data.", 69 | "locale":"nl_NL" 70 | }' 71 | ), 72 | $this->getMockClient()->getLastRequest() 73 | ); 74 | 75 | $this->assertInstanceOf(CreateCustomerResponse::class, $response); 76 | $this->assertSame('cst_bSNBBJBzdG', $response->getCustomerReference()); 77 | 78 | $this->assertTrue($response->isSuccessful()); 79 | $this->assertJsonStringEqualsJsonString( 80 | '{"resource":"customer","id":"cst_bSNBBJBzdG","mode":"test","name":"John Doe","email":"john@doe.com","locale":"nl_NL","metadata":"Just some meta data.","createdAt":"2018-07-19T12:58:47+00:00","_links":{"self":{"href":"https:\/\/api.mollie.com\/v2\/customers\/cst_6HUkmjwzBB","type":"application\/hal+json"},"documentation":{"href":"https:\/\/docs.mollie.com\/reference\/v2\/customers-api\/create-customer","type":"text\/html"}}}', 81 | $response->getMessage() 82 | ); 83 | } 84 | 85 | public function testSendFailure() 86 | { 87 | $this->setMockHttpResponse('CreateCustomerFailure.txt'); 88 | $response = $this->request->send(); 89 | 90 | $this->assertEqualRequest(new Request("POST", "https://api.mollie.com/v2/customers"), $this->getMockClient()->getLastRequest()); 91 | 92 | $this->assertInstanceOf(CreateCustomerResponse::class, $response); 93 | $this->assertFalse($response->isSuccessful()); 94 | $this->assertFalse($response->isRedirect()); 95 | $this->assertNull($response->getTransactionReference()); 96 | $this->assertSame('{"status":401,"title":"Unauthorized Request","detail":"Missing authentication, or failed to authenticate","_links":{"documentation":{"href":"https:\/\/docs.mollie.com\/guides\/authentication","type":"text\/html"}}}', $response->getMessage()); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /tests/Message/CreateShipmentRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new CreateShipmentRequest($this->getHttpClient(), $this->getHttpRequest()); 27 | 28 | $this->request->initialize(array( 29 | 'apiKey' => 'mykey', 30 | 'transactionReference' => 'ord_xxx', 31 | 'items' => [ 32 | [ 33 | 'id' => 'odl_dgtxyl', 34 | 'quantity' => 1, 35 | ], 36 | [ 37 | 'id' => 'odl_jp31jz', 38 | ] 39 | ], 40 | 'tracking' => [ 41 | 'carrier' => 'PostNL', 42 | 'code' => '3SKABA000000000', 43 | 'url' => 'http://postnl.nl/tracktrace/?B=3SKABA000000000&P=1016EE&D=NL&T=C', 44 | ] 45 | )); 46 | } 47 | 48 | /** 49 | * @throws InvalidRequestException 50 | */ 51 | public function testData() 52 | { 53 | $data = $this->request->getData(); 54 | 55 | $this->assertSame("odl_dgtxyl", $data['lines'][0]['id']); 56 | $this->assertSame(1, $data['lines'][0]['quantity']); 57 | $this->assertCount(2, $data['lines'][0]); 58 | $this->assertSame("odl_jp31jz", $data['lines'][1]['id']); 59 | $this->assertCount(1, $data['lines'][1]); 60 | 61 | $this->assertSame([ 62 | 'carrier' => 'PostNL', 63 | 'code' => '3SKABA000000000', 64 | 'url' => 'http://postnl.nl/tracktrace/?B=3SKABA000000000&P=1016EE&D=NL&T=C', 65 | ], $data['tracking']); 66 | 67 | $this->assertCount(2, $data); 68 | } 69 | 70 | public function testSendSuccess() 71 | { 72 | $this->setMockHttpResponse('CreateShipmentSuccess.txt'); 73 | 74 | /** @var CreateShipmentResponse $response */ 75 | $response = $this->request->send(); 76 | 77 | $orderId = $this->request->getTransactionReference(); 78 | 79 | $this->assertEqualRequest( 80 | new Request( 81 | "POST", 82 | "https://api.mollie.com/v2/orders/{$orderId}/shipments", 83 | [], 84 | '{ 85 | "lines": [ 86 | { 87 | "id": "odl_dgtxyl", 88 | "quantity": 1 89 | }, 90 | { 91 | "id": "odl_jp31jz" 92 | } 93 | ], 94 | "tracking": { 95 | "carrier": "PostNL", 96 | "code": "3SKABA000000000", 97 | "url": "http://postnl.nl/tracktrace/?B=3SKABA000000000&P=1016EE&D=NL&T=C" 98 | } 99 | }' 100 | ), 101 | $this->getMockClient()->getLastRequest() 102 | ); 103 | 104 | $this->assertInstanceOf(CreateShipmentResponse::class, $response); 105 | $this->assertSame('shp_3wmsgCJN4U', $response->getTransactionReference()); 106 | 107 | $this->assertTrue($response->isSuccessful()); 108 | 109 | $this->assertCount(2, $response->getLines()); 110 | $line = $response->getLines()[0]; 111 | 112 | $this->assertSame('5702016116977', $line['sku']); 113 | $this->assertSame(1, $line['quantity']); 114 | $this->assertSame('299.00', $line['totalAmount']['value']); 115 | 116 | $this->assertCount(2, $response->getItems()->all()); 117 | 118 | /** @var Item $item */ 119 | $item = $response->getItems()->all()[0]; 120 | $this->assertSame('5702016116977', $item->getSku()); 121 | $this->assertSame(1, $item->getQuantity()); 122 | $this->assertSame('299.00', $item->getTotalAmount()); 123 | 124 | // We cannot parse _links, rest should match 125 | unset($line['_links']); 126 | $this->assertSame(array_keys($line), array_keys($item->getParameters())); 127 | 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /tests/Message/FetchCustomerMandatesRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new FetchCustomerMandatesRequest($this->getHttpClient(), $this->getHttpRequest()); 23 | $this->request->initialize( 24 | array( 25 | 'apiKey' => 'mykey', 26 | 'customerReference' => 'cst_R6JLAuqEgm', 27 | ) 28 | ); 29 | } 30 | 31 | /** 32 | * @throws InvalidRequestException 33 | */ 34 | public function testGetData() 35 | { 36 | $data = $this->request->getData(); 37 | 38 | $this->assertEmpty($data); 39 | } 40 | 41 | public function testSendSuccess() 42 | { 43 | $this->setMockHttpResponse("FetchCustomerMandatesSuccess.txt"); 44 | 45 | $response = $this->request->send(); 46 | 47 | $this->assertEqualRequest(new Request("GET", "https://api.mollie.com/v2/customers/cst_R6JLAuqEgm/mandates"), $this->getMockClient()->getLastRequest()); 48 | 49 | $this->assertInstanceOf(FetchCustomerMandatesResponse::class, $response); 50 | 51 | $mandates = $response->getMandates(); 52 | 53 | $this->assertSame("mdt_AcQl5fdL4h", $mandates[0]['id']); 54 | $this->assertSame("directdebit", $mandates[0]['method']); 55 | 56 | $this->assertTrue($response->hasValidMandates()); 57 | $this->assertJsonStringEqualsJsonString( 58 | '{"count":5,"_embedded":{"mandates":[{"resource":"mandate","id":"mdt_AcQl5fdL4h","mode":"test","status":"valid","method":"directdebit","details":{"consumerName":"John Doe","consumerAccount":"NL55INGB0000000000","consumerBic":"INGBNL2A"},"mandateReference":null,"signatureDate":"2018-05-07","createdAt":"2018-05-07T10:49:08+00:00","_links":{"self":{"href":"https:\/\/api.mollie.com\/v2\/customers\/cst_8wmqcHMN4U\/mandates\/mdt_AcQl5fdL4h","type":"application\/hal+json"},"customer":{"href":"https:\/\/api.mollie.com\/v2\/customers\/cst_8wmqcHMN4U","type":"application\/hal+json"},"documentation":{"href":"https:\/\/mollie.com\/en\/docs\/reference\/customers\/create-mandate","type":"text\/html"}}},[],[],[],[]]},"_links":{"self":{"href":"https:\/\/api.mollie.com\/v2\/customers\/cst_8wmqcHMN4U\/mandates?limit=5","type":"application\/hal+json"},"previous":null,"next":{"href":"https:\/\/api.mollie.com\/v2\/customers\/cst_8wmqcHMN4U\/mandates?from=mdt_AcQl5fdL4h&limit=5","type":"application\/hal+json"},"documentation":{"href":"https:\/\/docs.mollie.com\/reference\/v2\/mandates-api\/revoke-mandate","type":"text\/html"}}}', 59 | $response->getMessage() 60 | ); 61 | } 62 | 63 | public function testSendFailure() 64 | { 65 | $this->setMockHttpResponse('FetchCustomerMandatesFailure.txt'); 66 | $response = $this->request->send(); 67 | 68 | $this->assertFalse($response->isSuccessful()); 69 | $this->assertFalse($response->isRedirect()); 70 | $this->assertJsonStringEqualsJsonString( 71 | '{"status":404,"title":"Not Found","detail":"No customer exists with token cst_6HUkmjwzBBa.","_links":{"documentation":{"href":"https:\/\/docs.mollie.com\/guides\/handling-errors","type":"text\/html"}}}', 72 | $response->getMessage() 73 | ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /tests/Message/FetchCustomerRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new FetchCustomerRequest($this->getHttpClient(), $this->getHttpRequest()); 23 | $this->request->initialize( 24 | array( 25 | 'apiKey' => 'mykey', 26 | 'customerReference' => 'cst_bSNBBJBzdG', 27 | ) 28 | ); 29 | } 30 | 31 | /** 32 | * @throws InvalidRequestException 33 | */ 34 | public function testGetData() 35 | { 36 | $data = $this->request->getData(); 37 | 38 | $this->assertCount(0, $data); 39 | } 40 | 41 | public function testSendSuccess() 42 | { 43 | $this->setMockHttpResponse('FetchCustomerSuccess.txt'); 44 | 45 | /** @var FetchCustomerResponse $response */ 46 | $response = $this->request->send(); 47 | 48 | $this->assertEqualRequest(new Request("GET", "https://api.mollie.com/v2/customers/cst_bSNBBJBzdG"), $this->getMockClient()->getLastRequest()); 49 | 50 | $this->assertInstanceOf(FetchCustomerResponse::class, $response); 51 | $this->assertSame('cst_bSNBBJBzdG', $response->getCustomerReference()); 52 | 53 | $this->assertTrue($response->isSuccessful()); 54 | $this->assertJsonStringEqualsJsonString( 55 | '{"resource":"customer","id":"cst_bSNBBJBzdG","mode":"test","name":"John Doe","email":"john@doe.com","locale":"nl_NL","metadata":null,"createdAt":"2018-07-19T12:58:47+00:00","_links":{"self":{"href":"https:\/\/api.mollie.com\/v2\/customers\/cst_6HUkmjwzBB","type":"application\/hal+json"},"documentation":{"href":"https:\/\/docs.mollie.com\/reference\/v2\/customers-api\/get-customer","type":"text\/html"}}}', 56 | $response->getMessage() 57 | ); 58 | } 59 | 60 | public function testSendFailure() 61 | { 62 | $this->setMockHttpResponse('FetchCustomerFailure.txt'); 63 | 64 | /** @var FetchCustomerResponse $response */ 65 | $response = $this->request->send(); 66 | 67 | $this->assertEqualRequest(new Request("GET", "https://api.mollie.com/v2/customers/cst_bSNBBJBzdG"), $this->getMockClient()->getLastRequest()); 68 | 69 | $this->assertInstanceOf(FetchCustomerResponse::class, $response); 70 | $this->assertFalse($response->isSuccessful()); 71 | $this->assertFalse($response->isRedirect()); 72 | $this->assertNull($response->getCustomerReference()); 73 | $this->assertSame('{"status":404,"title":"Not Found","detail":"No customer exists with token cst_6HUkmjwzBBa.","_links":{"documentation":{"href":"https:\/\/docs.mollie.com\/guides\/handling-errors","type":"text\/html"}}}', $response->getMessage()); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /tests/Message/FetchIssuersRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new FetchIssuersRequest($this->getHttpClient(), $this->getHttpRequest()); 24 | $this->request->initialize(array( 25 | 'apiKey' => 'mykey' 26 | )); 27 | } 28 | 29 | /** 30 | * @throws InvalidRequestException 31 | */ 32 | public function testGetData() 33 | { 34 | $data = $this->request->getData(); 35 | 36 | $this->assertEmpty($data); 37 | } 38 | 39 | public function testSendSuccess() 40 | { 41 | $this->setMockHttpResponse('FetchIssuersSuccess.txt'); 42 | $response = $this->request->send(); 43 | 44 | $this->assertEqualRequest( 45 | new Request("GET", "https://api.mollie.com/v2/methods/ideal?include=issuers"), 46 | $this->getMockClient()->getLastRequest() 47 | ); 48 | 49 | $this->assertInstanceOf(FetchIssuersResponse::class, $response); 50 | $this->assertTrue($response->isSuccessful()); 51 | $this->assertFalse($response->isRedirect()); 52 | $this->assertNull($response->getTransactionReference()); 53 | 54 | $expectedIssuer = new Issuer('ideal_ABNANL2A', 'ABN AMRO', 'ideal'); 55 | $expectedIssuer2 = new Issuer('ideal_ASNBNL21', 'ASN Bank', 'ideal'); 56 | 57 | $this->assertEquals(array($expectedIssuer, $expectedIssuer2), $response->getIssuers()); 58 | } 59 | 60 | public function testSendFailure() 61 | { 62 | $this->setMockHttpResponse('FetchIssuersFailure.txt'); 63 | $response = $this->request->send(); 64 | 65 | $this->assertEqualRequest( 66 | new Request("GET", "https://api.mollie.com/v2/methods/ideal?include=issuers"), 67 | $this->getMockClient()->getLastRequest() 68 | ); 69 | 70 | $this->assertInstanceOf(FetchIssuersResponse::class, $response); 71 | $this->assertFalse($response->isSuccessful()); 72 | $this->assertFalse($response->isRedirect()); 73 | $this->assertNull($response->getTransactionReference()); 74 | $this->assertSame('{"status":401,"title":"Unauthorized Request","detail":"Missing authentication, or failed to authenticate","_links":{"documentation":{"href":"https:\/\/docs.mollie.com\/guides\/authentication","type":"text\/html"}}}', $response->getMessage()); 75 | $this->assertEmpty($response->getIssuers()); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /tests/Message/FetchOrderRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new FetchOrderRequest($this->getHttpClient(), $this->getHttpRequest()); 27 | $this->request->initialize( 28 | array( 29 | 'apiKey' => 'mykey', 30 | 'transactionReference' => 'ord_kEn1PlbGa', 31 | ) 32 | ); 33 | } 34 | 35 | /** 36 | * @throws InvalidRequestException 37 | */ 38 | public function testGetData() 39 | { 40 | $data = $this->request->getData(); 41 | 42 | $this->assertSame("ord_kEn1PlbGa", $data['id']); 43 | $this->assertCount(1, $data); 44 | } 45 | 46 | public function testSendSuccess() 47 | { 48 | $this->setMockHttpResponse('FetchOrderSuccess.txt'); 49 | /** @var FetchOrderResponse $response */ 50 | $response = $this->request->send(); 51 | 52 | $this->assertEqualRequest( 53 | new Request( 54 | "GET", 55 | "https://api.mollie.com/v2/orders/ord_kEn1PlbGa" 56 | ), 57 | $this->getMockClient()->getLastRequest() 58 | ); 59 | 60 | 61 | $this->assertInstanceOf(FetchOrderResponse::class, $response); 62 | $this->assertTrue($response->isSuccessful()); 63 | $this->assertFalse($response->isPaid()); 64 | $this->assertFalse($response->isCancelled()); 65 | $this->assertFalse($response->isPaidOut()); 66 | $this->assertTrue($response->isRedirect()); 67 | $this->assertFalse($response->isRefunded()); 68 | $this->assertFalse($response->isPartialRefunded()); 69 | $this->assertSame("created", $response->getStatus()); 70 | $this->assertSame('ord_kEn1PlbGa', $response->getTransactionReference()); 71 | $this->assertSame("1027.99", $response->getAmount()); 72 | 73 | $this->assertCount(2, $response->getLines()); 74 | $line = $response->getLines()[0]; 75 | 76 | $this->assertSame('5702016116977', $line['sku']); 77 | $this->assertSame(2, $line['quantity']); 78 | $this->assertSame('0.00', $line['amountShipped']['value']); 79 | 80 | $this->assertCount(2, $response->getItems()->all()); 81 | 82 | /** @var Item $item */ 83 | $item = $response->getItems()->all()[0]; 84 | $this->assertSame('5702016116977', $item->getSku()); 85 | $this->assertSame(2, $item->getQuantity()); 86 | $this->assertSame('0.00', $item->getAmountShipped()); 87 | 88 | // We cannot parse _links, rest should match 89 | unset($line['_links']); 90 | $this->assertSame(array_keys($line), array_keys($item->getParameters())); 91 | } 92 | 93 | public function testSendDataWithIncludingPayments() 94 | { 95 | $expectedData = ['_embedded' => 'some-payments']; 96 | 97 | $clientResponse = $this->createMock(ResponseInterface::class); 98 | $clientResponse->expects(self::once()) 99 | ->method('getBody') 100 | ->willReturn(\json_encode($expectedData)); 101 | 102 | $httpClient = $this->createMock(ClientInterface::class); 103 | $httpClient->expects(self::once()) 104 | ->method('request') 105 | ->with( 106 | FetchOrderRequest::GET, 107 | 'https://api.mollie.com/v2/orders/ord_kEn1PlbGa?embed=payments', 108 | $this->callback(function ($headers) { 109 | return $headers['Authorization'] == 'Bearer mykey'; 110 | }), 111 | null 112 | )->willReturn($clientResponse); 113 | 114 | $request = new FetchOrderRequest($httpClient, $this->getHttpRequest()); 115 | $request->initialize( 116 | [ 117 | 'apiKey' => 'mykey', 118 | 'transactionReference' => 'ord_kEn1PlbGa', 119 | 'includePayments' => true, 120 | ] 121 | ); 122 | 123 | $response = $request->sendData(['id' => 'ord_kEn1PlbGa']); 124 | 125 | $this->assertInstanceOf(FetchOrderResponse::class, $response); 126 | $this->assertEquals($request, $response->getRequest()); 127 | $this->assertEquals($expectedData, $response->getData()); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /tests/Message/FetchPaymentMethodsRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new FetchPaymentMethodsRequest($this->getHttpClient(), $this->getHttpRequest()); 26 | $this->request->initialize([ 27 | 'apiKey' => 'mykey', 28 | 'amount' => '22.56', 29 | 'billingCountry' => 'SE', 30 | 'currency' => 'SEK', 31 | 'locale' => 'sv_SE', 32 | 'resource' => 'orders', 33 | 'sequenceType' => 'oneoff', 34 | 'includeWallets' => 'applepay', 35 | ]); 36 | } 37 | 38 | /** 39 | * @throws InvalidRequestException 40 | */ 41 | public function testGetData() 42 | { 43 | $data = $this->request->getData(); 44 | 45 | $this->assertSame('SEK', $data['amount']['currency']); 46 | $this->assertSame('22.56', $data['amount']['value']); 47 | $this->assertSame('SE', $data['billingCountry']); 48 | $this->assertSame('sv_SE', $data['locale']); 49 | $this->assertSame('orders', $data['resource']); 50 | $this->assertSame('oneoff', $data['sequenceType']); 51 | $this->assertSame('applepay', $data['includeWallets']); 52 | } 53 | 54 | /** 55 | * @throws InvalidRequestException 56 | */ 57 | public function testOptionalParameters() 58 | { 59 | $this->request->initialize([ 60 | 'apiKey' => 'mykey', 61 | ]); 62 | $this->assertEmpty(array_filter($this->request->getData())); 63 | $this->request->send(); 64 | $this->assertEqualRequest( 65 | new Request('GET', 'https://api.mollie.com/v2/methods'), 66 | $this->getMockClient()->getLastRequest() 67 | ); 68 | } 69 | 70 | /** 71 | * Require both amount and currency when either one is set. 72 | * 73 | * @throws InvalidRequestException 74 | */ 75 | public function testRequiredAmountParameters() 76 | { 77 | $this->expectException(InvalidRequestException::class); 78 | 79 | $this->request->initialize([ 80 | 'apiKey' => 'mykey', 81 | 'amount' => '78.02', 82 | ]); 83 | $this->request->getData(); 84 | } 85 | 86 | public function testSendSuccess() 87 | { 88 | $this->setMockHttpResponse('FetchPaymentMethodsSuccess.txt'); 89 | $response = $this->request->send(); 90 | 91 | $this->assertEqualRequest( 92 | new Request('GET', self::$expectedRequestUri), 93 | $this->getMockClient()->getLastRequest() 94 | ); 95 | 96 | $this->assertInstanceOf(FetchPaymentMethodsResponse::class, $response); 97 | $this->assertTrue($response->isSuccessful()); 98 | $this->assertFalse($response->isRedirect()); 99 | $this->assertNull($response->getTransactionReference()); 100 | $paymentMethods = $response->getPaymentMethods(); 101 | $this->assertCount(12, $paymentMethods); 102 | 103 | $paymentMethod = new PaymentMethod('ideal', 'iDEAL'); 104 | 105 | $this->assertEquals($paymentMethod, $paymentMethods[0]); 106 | } 107 | 108 | public function testSendFailure() 109 | { 110 | $this->setMockHttpResponse('FetchPaymentMethodsFailure.txt'); 111 | $response = $this->request->send(); 112 | 113 | $this->assertEqualRequest( 114 | new Request('GET', self::$expectedRequestUri), 115 | $this->getMockClient()->getLastRequest() 116 | ); 117 | 118 | $this->assertInstanceOf(FetchPaymentMethodsResponse::class, $response); 119 | $this->assertFalse($response->isSuccessful()); 120 | $this->assertFalse($response->isRedirect()); 121 | $this->assertNull($response->getTransactionReference()); 122 | $this->assertSame('{"status":401,"title":"Unauthorized Request","detail":"Missing authentication, or failed to authenticate","_links":{"documentation":{"href":"https:\/\/docs.mollie.com\/guides\/authentication","type":"text\/html"}}}', $response->getMessage()); 123 | $this->assertEmpty($response->getPaymentMethods()); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /tests/Message/FetchTransactionRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new FetchTransactionRequest($this->getHttpClient(), $this->getHttpRequest()); 23 | $this->request->initialize( 24 | array( 25 | 'apiKey' => 'mykey', 26 | 'transactionReference' => 'tr_WDqYK6vllg', 27 | ) 28 | ); 29 | } 30 | 31 | /** 32 | * @throws InvalidRequestException 33 | */ 34 | public function testGetData() 35 | { 36 | $data = $this->request->getData(); 37 | 38 | $this->assertSame("tr_WDqYK6vllg", $data['id']); 39 | $this->assertCount(1, $data); 40 | } 41 | 42 | public function testSendSuccess() 43 | { 44 | $this->setMockHttpResponse('FetchTransactionSuccess.txt'); 45 | /** @var FetchTransactionResponse $response */ 46 | $response = $this->request->send(); 47 | 48 | $this->assertEqualRequest( 49 | new Request( 50 | "GET", 51 | "https://api.mollie.com/v2/payments/tr_WDqYK6vllg" 52 | ), 53 | $this->getMockClient()->getLastRequest() 54 | ); 55 | 56 | 57 | $this->assertInstanceOf(FetchTransactionResponse::class, $response); 58 | $this->assertTrue($response->isSuccessful()); 59 | $this->assertTrue($response->isPaid()); 60 | $this->assertFalse($response->isCancelled()); 61 | $this->assertFalse($response->isPaidOut()); 62 | $this->assertTrue($response->isRedirect()); 63 | $this->assertFalse($response->isRefunded()); 64 | $this->assertFalse($response->isPartialRefunded()); 65 | $this->assertSame("paid", $response->getStatus()); 66 | $this->assertSame('tr_WDqYK6vllg', $response->getTransactionReference()); 67 | $this->assertSame("10.00", $response->getAmount()); 68 | } 69 | 70 | public function testSendExpired() 71 | { 72 | $this->setMockHttpResponse('FetchTransactionExpired.txt'); 73 | $response = $this->request->send(); 74 | 75 | $this->assertEqualRequest( 76 | new Request( 77 | "GET", 78 | "https://api.mollie.com/v2/payments/tr_WDqYK6vllg" 79 | ), 80 | $this->getMockClient()->getLastRequest() 81 | ); 82 | 83 | $this->assertInstanceOf(FetchTransactionResponse::class, $response); 84 | $this->assertTrue($response->isSuccessful()); 85 | $this->assertTrue($response->isRedirect()); 86 | $this->assertSame('tr_WDqYK6vllg', $response->getTransactionReference()); 87 | $this->assertTrue($response->isExpired()); 88 | } 89 | 90 | public function testSendFailure() 91 | { 92 | $this->setMockHttpResponse('FetchTransaction404Failure.txt'); 93 | $response = $this->request->send(); 94 | 95 | $this->assertEqualRequest( 96 | new Request( 97 | "GET", 98 | "https://api.mollie.com/v2/payments/tr_WDqYK6vllg" 99 | ), 100 | $this->getMockClient()->getLastRequest() 101 | ); 102 | 103 | $this->assertInstanceOf(FetchTransactionResponse::class, $response); 104 | $this->assertFalse($response->isSuccessful()); 105 | $this->assertFalse($response->isRedirect()); 106 | $this->assertNull($response->getTransactionReference()); 107 | $this->assertEquals(404, $response->getStatus()); 108 | $this->assertNull($response->getAmount()); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /tests/Message/RefundRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new RefundRequest($this->getHttpClient(), $this->getHttpRequest()); 22 | $this->request->initialize([ 23 | 'apiKey' => 'mykey', 24 | 'transactionReference' => 'tr_WDqYK6vllg', 25 | 'amount' => '12.00', 26 | 'currency' => 'EUR', 27 | ]); 28 | } 29 | 30 | /** 31 | * @throws \Omnipay\Common\Exception\InvalidRequestException 32 | */ 33 | public function testGetData() 34 | { 35 | $this->request->initialize([ 36 | 'apiKey' => 'mykey', 37 | 'amount' => '12.00', 38 | 'currency' => 'EUR', 39 | 'transactionReference' => 'tr_WDqYK6vllg' 40 | ]); 41 | 42 | $data = $this->request->getData(); 43 | 44 | $this->assertSame(["value" => "12.00", "currency" => "EUR"], $data['amount']); 45 | $this->assertCount(1, $data); 46 | } 47 | 48 | public function testGetDataWithoutAmount() 49 | { 50 | $this->expectException(\Omnipay\Common\Exception\InvalidRequestException::class); 51 | 52 | $this->request->initialize( 53 | [ 54 | 'apiKey' => 'mykey', 55 | 'transactionReference' => 'tr_WDqYK6vllg', 56 | ] 57 | ); 58 | 59 | $data = $this->request->getData(); 60 | 61 | $this->assertCount(0, $data); 62 | } 63 | 64 | public function testSendSuccess() 65 | { 66 | $this->setMockHttpResponse('RefundSuccess.txt'); 67 | /** @var RefundResponse $response */ 68 | $response = $this->request->send(); 69 | 70 | $this->assertEqualRequest( 71 | new Request( 72 | "POST", 73 | "https://api.mollie.com/v2/payments/tr_WDqYK6vllg/refunds", 74 | [], 75 | '{"amount":{"value":"12.00","currency":"EUR"}}' 76 | ), 77 | $this->getMockClient()->getLastRequest() 78 | ); 79 | 80 | 81 | $this->assertInstanceOf(RefundResponse::class, $response); 82 | $this->assertTrue($response->isSuccessful()); 83 | $this->assertFalse($response->isRedirect()); 84 | $this->assertSame('tr_WDqYK6vllg', $response->getTransactionReference()); 85 | $this->assertSame('re_4qqhO89gsT', $response->getTransactionId()); 86 | } 87 | 88 | public function test401Failure() 89 | { 90 | $this->setMockHttpResponse('Refund401Failure.txt'); 91 | /** @var RefundResponse $response */ 92 | $response = $this->request->send(); 93 | 94 | $this->assertEqualRequest( 95 | new Request("POST", "https://api.mollie.com/v2/payments/tr_WDqYK6vllg/refunds", [], ''), 96 | $this->getMockClient()->getLastRequest() 97 | ); 98 | 99 | $this->assertInstanceOf(RefundResponse::class, $response); 100 | $this->assertFalse($response->isSuccessful()); 101 | $this->assertEquals('{"status":401,"title":"Unauthorized Request","detail":"Missing authentication, or failed to authenticate","_links":{"documentation":{"href":"https:\/\/docs.mollie.com\/guides\/authentication","type":"text\/html"}}}', $response->getMessage()); 102 | } 103 | 104 | public function test422Failure() 105 | { 106 | $this->setMockHttpResponse('Refund422Failure.txt'); 107 | /** @var RefundResponse $response */ 108 | $response = $this->request->send(); 109 | 110 | $this->assertEqualRequest( 111 | new Request( 112 | "POST", 113 | "https://api.mollie.com/v2/payments/tr_WDqYK6vllg/refunds", 114 | [], 115 | '{"amount":{"value":"12.00","currency":"EUR"}}' 116 | ), 117 | $this->getMockClient()->getLastRequest() 118 | ); 119 | 120 | $this->assertInstanceOf(RefundResponse::class, $response); 121 | $this->assertFalse($response->isSuccessful()); 122 | $this->assertEquals('{"status":422,"title":"Unprocessable Entity","detail":"The payment method is invalid","field":"method","_links":{"documentation":{"href":"https:\/\/docs.mollie.com\/guides\/handling-errors","type":"text\/html"}}}', $response->getMessage()); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /tests/Message/RevokeCustomerMandateRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new RevokeCustomerMandateRequest($this->getHttpClient(), $this->getHttpRequest()); 23 | 24 | $this->request->initialize([ 25 | 'apiKey' => "mykey", 26 | 'customerReference' => 'cst_bSNBBJBzdG', 27 | 'mandateId' => "mdt_pWUnw6pkBN", 28 | ]); 29 | } 30 | 31 | /** 32 | * @throws InvalidRequestException 33 | */ 34 | public function testData() 35 | { 36 | $this->request->initialize([ 37 | 'apiKey' => "mykey", 38 | 'customerReference' => 'cst_bSNBBJBzdG', 39 | 'mandateId' => "mdt_pWUnw6pkBN", 40 | ]); 41 | 42 | $data = $this->request->getData(); 43 | $this->assertSame("cst_bSNBBJBzdG", $data['customerReference']); 44 | $this->assertSame("mdt_pWUnw6pkBN", $data['mandateId']); 45 | } 46 | 47 | public function testSendSuccess() 48 | { 49 | $this->setMockHttpResponse('RevokeCustomerMandateSuccess.txt'); 50 | 51 | /** @var RevokeCustomerMandateResponse $response */ 52 | $response = $this->request->send(); 53 | 54 | $this->assertEqualRequest(new Request("DELETE", "https://api.mollie.com/v2/customers/cst_bSNBBJBzdG/mandates/mdt_pWUnw6pkBN"), $this->getMockClient()->getLastRequest()); 55 | 56 | $this->assertInstanceOf(RevokeCustomerMandateResponse::class, $response); 57 | 58 | $this->assertTrue($response->isSuccessful()); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tests/Message/UpdateCustomerRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new UpdateCustomerRequest($this->getHttpClient(), $this->getHttpRequest()); 24 | 25 | $this->request->initialize(array( 26 | 'apiKey' => 'mykey', 27 | 'customerReference' => 'cst_bSNBBJBzdG', 28 | 'description' => 'Jane Doe', 29 | 'email' => 'john@doe.com', 30 | 'locale' => 'nl_NL', 31 | 'metadata' => 'Just some meta data.', 32 | )); 33 | } 34 | 35 | /** 36 | * @throws InvalidRequestException 37 | */ 38 | public function testData() 39 | { 40 | $this->request->initialize(array( 41 | 'apiKey' => 'mykey', 42 | 'customerReference' => 'cst_bSNBBJBzdG', 43 | 'description' => 'Jane Doe', 44 | 'email' => 'john@doe.com', 45 | 'metadata' => 'Just some meta data.', 46 | )); 47 | 48 | $data = $this->request->getData(); 49 | 50 | $this->assertSame("Jane Doe", $data['name']); 51 | $this->assertSame('john@doe.com', $data['email']); 52 | $this->assertSame('Just some meta data.', $data['metadata']); 53 | $this->assertCount(4, $data); 54 | } 55 | 56 | public function testSendSuccess() 57 | { 58 | $this->setMockHttpResponse('UpdateCustomerSuccess.txt'); 59 | 60 | /** @var UpdateCustomerResponse $response */ 61 | $response = $this->request->send(); 62 | 63 | $this->assertEqualRequest( 64 | new Request( 65 | "POST", 66 | "https://api.mollie.com/v2/customers/cst_bSNBBJBzdG", 67 | [], 68 | '{ 69 | "name": "Jane Doe", 70 | "email": "john@doe.com", 71 | "metadata": "Just some meta data.", 72 | "locale": "nl_NL" 73 | }' 74 | ), 75 | $this->getMockClient()->getLastRequest() 76 | ); 77 | 78 | $this->assertInstanceOf(UpdateCustomerResponse::class, $response); 79 | $this->assertSame('cst_bSNBBJBzdG', $response->getCustomerReference()); 80 | 81 | $this->assertTrue($response->isSuccessful()); 82 | $this->assertJsonStringEqualsJsonString( 83 | '{"resource":"customer","id":"cst_bSNBBJBzdG","mode":"test","name":"Jane Doe","email":"john@doe.com","locale":"nl_NL","metadata":"Just some meta data.","createdAt":"2018-07-19T12:58:47+00:00","_links":{"self":{"href":"https:\/\/api.mollie.com\/v2\/customers\/cst_6HUkmjwzBB","type":"application\/hal+json"},"documentation":{"href":"https:\/\/docs.mollie.com\/reference\/v2\/customers-api\/update-customer","type":"text\/html"}}}', 84 | $response->getMessage() 85 | ); 86 | } 87 | 88 | public function testSendFailure() 89 | { 90 | $this->setMockHttpResponse('UpdateCustomerFailure.txt'); 91 | 92 | /** @var UpdateCustomerResponse $response */ 93 | $response = $this->request->send(); 94 | 95 | $this->assertEqualRequest(new Request("POST", "https://api.mollie.com/v2/customers/cst_bSNBBJBzdG"), $this->getMockClient()->getLastRequest()); 96 | 97 | $this->assertInstanceOf(UpdateCustomerResponse::class, $response); 98 | $this->assertFalse($response->isSuccessful()); 99 | $this->assertFalse($response->isRedirect()); 100 | $this->assertNull($response->getCustomerReference()); 101 | $this->assertSame('{"status":401,"title":"Unauthorized Request","detail":"Missing authentication, or failed to authenticate","_links":{"documentation":{"href":"https:\/\/docs.mollie.com\/guides\/authentication","type":"text\/html"}}}', $response->getMessage()); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /tests/Mock/CompleteOrderSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Content-Type: application/hal+json 3 | 4 | { 5 | "resource": "order", 6 | "id": "ord_kEn1PlbGa", 7 | "profileId": "pfl_URR55HPMGx", 8 | "method": "ideal", 9 | "amount": { 10 | "value": "1027.99", 11 | "currency": "EUR" 12 | }, 13 | "status": "created", 14 | "isCancelable": true, 15 | "metadata": null, 16 | "createdAt": "2018-08-02T09:29:56+00:00", 17 | "expiresAt": "2018-08-30T09:29:56+00:00", 18 | "mode": "live", 19 | "locale": "nl_NL", 20 | "billingAddress": { 21 | "organizationName": "Mollie B.V.", 22 | "streetAndNumber": "Keizersgracht 313", 23 | "postalCode": "1016 EE", 24 | "city": "Amsterdam", 25 | "country": "nl", 26 | "givenName": "Luke", 27 | "familyName": "Skywalker", 28 | "email": "luke@skywalker.com" 29 | }, 30 | "orderNumber": "18475", 31 | "shippingAddress": { 32 | "organizationName": "Mollie B.V.", 33 | "streetAndNumber": "Keizersgracht 313", 34 | "postalCode": "1016 EE", 35 | "city": "Amsterdam", 36 | "country": "nl", 37 | "givenName": "Luke", 38 | "familyName": "Skywalker", 39 | "email": "luke@skywalker.com" 40 | }, 41 | "redirectUrl": "https://example.org/redirect", 42 | "lines": [ 43 | { 44 | "resource": "orderline", 45 | "id": "odl_dgtxyl", 46 | "orderId": "ord_pbjz8x", 47 | "name": "LEGO 42083 Bugatti Chiron", 48 | "sku": "5702016116977", 49 | "type": "physical", 50 | "status": "created", 51 | "isCancelable": false, 52 | "quantity": 2, 53 | "quantityShipped": 0, 54 | "amountShipped": { 55 | "value": "0.00", 56 | "currency": "EUR" 57 | }, 58 | "quantityRefunded": 0, 59 | "amountRefunded": { 60 | "value": "0.00", 61 | "currency": "EUR" 62 | }, 63 | "quantityCanceled": 0, 64 | "amountCanceled": { 65 | "value": "0.00", 66 | "currency": "EUR" 67 | }, 68 | "shippableQuantity": 0, 69 | "refundableQuantity": 0, 70 | "cancelableQuantity": 0, 71 | "unitPrice": { 72 | "value": "399.00", 73 | "currency": "EUR" 74 | }, 75 | "vatRate": "21.00", 76 | "vatAmount": { 77 | "value": "121.14", 78 | "currency": "EUR" 79 | }, 80 | "discountAmount": { 81 | "value": "100.00", 82 | "currency": "EUR" 83 | }, 84 | "totalAmount": { 85 | "value": "698.00", 86 | "currency": "EUR" 87 | }, 88 | "createdAt": "2018-08-02T09:29:56+00:00", 89 | "_links": { 90 | "productUrl": { 91 | "href": "https://shop.lego.com/nl-NL/Bugatti-Chiron-42083", 92 | "type": "text/html" 93 | }, 94 | "imageUrl": { 95 | "href": "https://sh-s7-live-s.legocdn.com/is/image//LEGO/42083_alt1?$main$", 96 | "type": "text/html" 97 | } 98 | } 99 | }, 100 | { 101 | "resource": "orderline", 102 | "id": "odl_jp31jz", 103 | "orderId": "ord_pbjz8x", 104 | "name": "LEGO 42056 Porsche 911 GT3 RS", 105 | "sku": "5702015594028", 106 | "type": "physical", 107 | "status": "created", 108 | "isCancelable": false, 109 | "quantity": 1, 110 | "quantityShipped": 0, 111 | "amountShipped": { 112 | "value": "0.00", 113 | "currency": "EUR" 114 | }, 115 | "quantityRefunded": 0, 116 | "amountRefunded": { 117 | "value": "0.00", 118 | "currency": "EUR" 119 | }, 120 | "quantityCanceled": 0, 121 | "amountCanceled": { 122 | "value": "0.00", 123 | "currency": "EUR" 124 | }, 125 | "shippableQuantity": 0, 126 | "refundableQuantity": 0, 127 | "cancelableQuantity": 0, 128 | "unitPrice": { 129 | "value": "329.99", 130 | "currency": "EUR" 131 | }, 132 | "vatRate": "21.00", 133 | "vatAmount": { 134 | "value": "57.27", 135 | "currency": "EUR" 136 | }, 137 | "totalAmount": { 138 | "value": "329.99", 139 | "currency": "EUR" 140 | }, 141 | "createdAt": "2018-08-02T09:29:56+00:00", 142 | "_links": { 143 | "productUrl": { 144 | "href": "https://shop.lego.com/nl-NL/Porsche-911-GT3-RS-42056", 145 | "type": "text/html" 146 | }, 147 | "imageUrl": { 148 | "href": "https://sh-s7-live-s.legocdn.com/is/image/LEGO/42056?$PDPDefault$", 149 | "type": "text/html" 150 | } 151 | } 152 | } 153 | ], 154 | "_embedded": { 155 | "payments": [ 156 | { 157 | "resource": "payment", 158 | "id": "tr_ncaPcAhuUV", 159 | "mode": "live", 160 | "createdAt": "2018-09-07T12:00:05+00:00", 161 | "amount": { 162 | "value": "1027.99", 163 | "currency": "EUR" 164 | }, 165 | "description": "Order #1337 (Lego cars)", 166 | "method": null, 167 | "metadata": null, 168 | "status": "open", 169 | "isCancelable": false, 170 | "locale": "nl_NL", 171 | "profileId": "pfl_URR55HPMGx", 172 | "orderId": "ord_kEn1PlbGa", 173 | "sequenceType": "oneoff", 174 | "redirectUrl": "https://example.org/redirect", 175 | "_links": { 176 | "self": { 177 | "href": "https://api.mollie.com/v2/payments/tr_ncaPcAhuUV", 178 | "type": "application/hal+json" 179 | }, 180 | "checkout": { 181 | "href": "https://www.mollie.com/payscreen/select-method/ncaPcAhuUV", 182 | "type": "text/html" 183 | }, 184 | "order": { 185 | "href": "https://api.mollie.com/v2/orders/ord_kEn1PlbGa", 186 | "type": "application/hal+json" 187 | } 188 | } 189 | } 190 | ] 191 | }, 192 | "_links": { 193 | "self": { 194 | "href": "https://api.mollie.com/v2/orders/ord_pbjz8x", 195 | "type": "application/hal+json" 196 | }, 197 | "checkout": { 198 | "href": "https://www.mollie.com/payscreen/order/checkout/pbjz8x", 199 | "type": "text/html" 200 | }, 201 | "documentation": { 202 | "href": "https://docs.mollie.com/reference/v2/orders-api/get-order", 203 | "type": "text/html" 204 | } 205 | } 206 | } -------------------------------------------------------------------------------- /tests/Mock/CompletePurchaseExpired.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "resource": "payment", 6 | "id": "tr_Qzin4iTWrU", 7 | "mode": "test", 8 | "createdAt": "2018-07-19T12:04:56+00:00", 9 | "amount": { 10 | "value": "100.00", 11 | "currency": "EUR" 12 | }, 13 | "description": "apex.sh performance test payment", 14 | "method": null, 15 | "metadata": null, 16 | "status": "expired", 17 | "expiredAt": "2018-07-19T12:21:04+00:00", 18 | "locale": "nl_NL", 19 | "profileId": "pfl_7N5qjbu42V", 20 | "sequenceType": "oneoff", 21 | "redirectUrl": "https://www.example.org/", 22 | "_links": { 23 | "self": { 24 | "href": "https://api.mollie.com/v2/payments/tr_wnUB738Suu", 25 | "type": "application/hal+json" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/Mock/CompletePurchaseSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "resource": "payment", 6 | "id": "tr_Qzin4iTWrU", 7 | "mode": "test", 8 | "createdAt": "2018-07-19T12:38:21+00:00", 9 | "amount": { 10 | "value": "10.00", 11 | "currency": "EUR" 12 | }, 13 | "description": "Order #1234", 14 | "method": "ideal", 15 | "metadata": null, 16 | "status": "paid", 17 | "paidAt": "2018-07-19T12:38:34+00:00", 18 | "amountRefunded": { 19 | "value": "0.00", 20 | "currency": "EUR" 21 | }, 22 | "amountRemaining": { 23 | "value": "35.00", 24 | "currency": "EUR" 25 | }, 26 | "locale": "nl_NL", 27 | "countryCode": "NL", 28 | "profileId": "pfl_7N5qjbu42V", 29 | "sequenceType": "oneoff", 30 | "redirectUrl": "http://mollie.com", 31 | "webhookUrl": "http://mollie.com", 32 | "settlementAmount": { 33 | "value": "10.00", 34 | "currency": "EUR" 35 | }, 36 | "details": { 37 | "consumerName": "T. TEST", 38 | "consumerAccount": "NL17RABO0213698412", 39 | "consumerBic": "INGBNL2A" 40 | }, 41 | "_links": { 42 | "self": { 43 | "href": "https://api.mollie.com/v2/payments/tr_2bMMNCF5A2", 44 | "type": "application/hal+json" 45 | }, 46 | "documentation": { 47 | "href": "https://docs.mollie.com/reference/v2/payments-api/get-payment", 48 | "type": "text/html" 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/Mock/CreateCustomerFailure.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 401 Unauthorized Request 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "status": 401, 6 | "title": "Unauthorized Request", 7 | "detail": "Missing authentication, or failed to authenticate", 8 | "_links": { 9 | "documentation": { 10 | "href": "https://docs.mollie.com/guides/authentication", 11 | "type": "text/html" 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /tests/Mock/CreateCustomerMandateFailure.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 401 Unauthorized Request 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "status": 401, 6 | "title": "Unauthorized Request", 7 | "detail": "Missing authentication, or failed to authenticate", 8 | "_links": { 9 | "documentation": { 10 | "href": "https://docs.mollie.com/guides/authentication", 11 | "type": "text/html" 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /tests/Mock/CreateCustomerMandateSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 201 Created 2 | Content-Type: application/json; charset=utf-8 3 | 4 | { 5 | "resource": "mandate", 6 | "id": "mdt_h3gAaD5zP", 7 | "mode": "test", 8 | "status": "valid", 9 | "method": "directdebit", 10 | "details": { 11 | "consumerName": "John Doe", 12 | "consumerAccount": "NL55INGB0000000000", 13 | "consumerBic": "INGBNL2A" 14 | }, 15 | "mandateReference": "YOUR-COMPANY-MD13804", 16 | "signatureDate": "2018-05-07", 17 | "createdAt": "2018-05-07T10:49:08+00:00", 18 | "_links": { 19 | "self": { 20 | "href": "https://api.mollie.com/v2/customers/cst_4qqhO89gsT/mandates/mdt_h3gAaD5zP", 21 | "type": "application/hal+json" 22 | }, 23 | "customer": { 24 | "href": "https://api.mollie.com/v2/customers/cst_4qqhO89gsT", 25 | "type": "application/hal+json" 26 | }, 27 | "documentation": { 28 | "href": "https://docs.mollie.com/reference/v2/mandates-api/create-mandate", 29 | "type": "text/html" 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /tests/Mock/CreateCustomerSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 201 Created 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "resource": "customer", 6 | "id": "cst_bSNBBJBzdG", 7 | "mode": "test", 8 | "name": "John Doe", 9 | "email": "john@doe.com", 10 | "locale": "nl_NL", 11 | "metadata": "Just some meta data.", 12 | "createdAt": "2018-07-19T12:58:47+00:00", 13 | "_links": { 14 | "self": { 15 | "href": "https://api.mollie.com/v2/customers/cst_6HUkmjwzBB", 16 | "type": "application/hal+json" 17 | }, 18 | "documentation": { 19 | "href": "https://docs.mollie.com/reference/v2/customers-api/create-customer", 20 | "type": "text/html" 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /tests/Mock/CreateOrderFailure.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 401 Unauthorized Request 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "status": 401, 6 | "title": "Unauthorized Request", 7 | "detail": "Missing authentication, or failed to authenticate", 8 | "_links": { 9 | "documentation": { 10 | "href": "https://docs.mollie.com/guides/authentication", 11 | "type": "text/html" 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /tests/Mock/CreateOrderRequest.txt: -------------------------------------------------------------------------------- 1 | { 2 | "amount": { 3 | "value": "1027.99", 4 | "currency": "EUR" 5 | }, 6 | "billingAddress": { 7 | "organizationName": "Mollie B.V.", 8 | "streetAndNumber": "Keizersgracht 313", 9 | "city": "Amsterdam", 10 | "region": "Noord-Holland", 11 | "postalCode": "1234AB", 12 | "country": "NL", 13 | "title": "Dhr", 14 | "givenName": "Piet", 15 | "familyName": "Mondriaan", 16 | "email": "piet@mondriaan.com", 17 | "phone": "+31208202070" 18 | }, 19 | "shippingAddress": { 20 | "organizationName": "Mollie B.V.", 21 | "streetAndNumber": "Prinsengracht 313", 22 | "streetAdditional": "4th floor", 23 | "city": "Haarlem", 24 | "region": "Noord-Holland", 25 | "postalCode": "5678AB", 26 | "country": "NL", 27 | "title": "Mr", 28 | "givenName": "Chuck", 29 | "familyName": "Norris", 30 | "email": "norris@chucknorrisfacts.net" 31 | }, 32 | "metadata": { 33 | "order_id": "1337", 34 | "description": "Lego cars" 35 | }, 36 | "consumerDateOfBirth": "1958-01-31", 37 | "locale": "nl_NL", 38 | "orderNumber": "1337", 39 | "redirectUrl": "https://example.org/redirect", 40 | "webhookUrl": "https://example.org/webhook", 41 | "method": "klarnapaylater", 42 | "lines": [ 43 | { 44 | "type": "physical", 45 | "sku": "5702016116977", 46 | "name": "LEGO 42083 Bugatti Chiron", 47 | "productUrl": "https://shop.lego.com/nl-NL/Bugatti-Chiron-42083", 48 | "imageUrl": "https://sh-s7-live-s.legocdn.com/is/image//LEGO/42083_alt1?$main$", 49 | "quantity": 2, 50 | "vatRate": "21.00", 51 | "unitPrice": { 52 | "currency": "EUR", 53 | "value": "399.00" 54 | }, 55 | "totalAmount": { 56 | "currency": "EUR", 57 | "value": "698.00" 58 | }, 59 | "discountAmount": { 60 | "currency": "EUR", 61 | "value": "100.00" 62 | }, 63 | "vatAmount": { 64 | "currency": "EUR", 65 | "value": "121.14" 66 | } 67 | }, 68 | { 69 | "type": "physical", 70 | "sku": "5702015594028", 71 | "name": "LEGO 42056 Porsche 911 GT3 RS", 72 | "productUrl": "https://shop.lego.com/nl-NL/Porsche-911-GT3-RS-42056", 73 | "imageUrl": "https://sh-s7-live-s.legocdn.com/is/image/LEGO/42056?$PDPDefault$", 74 | "quantity": 1, 75 | "vatRate": "21.00", 76 | "unitPrice": { 77 | "currency": "EUR", 78 | "value": "329.99" 79 | }, 80 | "totalAmount": { 81 | "currency": "EUR", 82 | "value": "329.99" 83 | }, 84 | "vatAmount": { 85 | "currency": "EUR", 86 | "value": "57.27" 87 | } 88 | } 89 | ] 90 | } -------------------------------------------------------------------------------- /tests/Mock/CreateOrderSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 201 Created 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "resource": "order", 6 | "id": "ord_pbjz8x", 7 | "profileId": "pfl_URR55HPMGx", 8 | "method": "klarnapaylater", 9 | "amount": { 10 | "value": "1027.99", 11 | "currency": "EUR" 12 | }, 13 | "status": "created", 14 | "isCancelable": true, 15 | "metadata": { 16 | "order_id": "1337", 17 | "description": "Lego cars" 18 | }, 19 | "createdAt": "2018-08-02T09:29:56+00:00", 20 | "expiresAt": "2018-08-30T09:29:56+00:00", 21 | "mode": "test", 22 | "locale": "nl_NL", 23 | "billingAddress": { 24 | "organizationName": "Mollie B.V.", 25 | "streetAndNumber": "Keizersgracht 313", 26 | "city": "Amsterdam", 27 | "region": "Noord-Holland", 28 | "postalCode": "1234AB", 29 | "country": "NL", 30 | "title": "Dhr.", 31 | "givenName": "Piet", 32 | "familyName": "Mondriaan", 33 | "email": "piet@mondriaan.com", 34 | "phone": "+31309202070" 35 | }, 36 | "consumerDateOfBirth": "1958-01-31", 37 | "orderNumber": "1337", 38 | "shippingAddress": { 39 | "organizationName": "Mollie B.V.", 40 | "streetAndNumber": "Keizersgracht 313", 41 | "streetAdditional": "4th floor", 42 | "city": "Haarlem", 43 | "region": "Noord-Holland", 44 | "postalCode": "5678AB", 45 | "country": "NL", 46 | "title": "Mr.", 47 | "givenName": "Chuck", 48 | "familyName": "Norris", 49 | "email": "norris@chucknorrisfacts.net" 50 | }, 51 | "redirectUrl": "https://example.org/redirect", 52 | "webhookUrl": "https://example.org/webhook", 53 | "lines": [ 54 | { 55 | "resource": "orderline", 56 | "id": "odl_dgtxyl", 57 | "orderId": "ord_pbjz8x", 58 | "name": "LEGO 42083 Bugatti Chiron", 59 | "sku": "5702016116977", 60 | "type": "physical", 61 | "status": "created", 62 | "isCancelable": false, 63 | "quantity": 2, 64 | "quantityShipped": 0, 65 | "amountShipped": { 66 | "value": "0.00", 67 | "currency": "EUR" 68 | }, 69 | "quantityRefunded": 0, 70 | "amountRefunded": { 71 | "value": "0.00", 72 | "currency": "EUR" 73 | }, 74 | "quantityCanceled": 0, 75 | "amountCanceled": { 76 | "value": "0.00", 77 | "currency": "EUR" 78 | }, 79 | "shippableQuantity": 0, 80 | "refundableQuantity": 0, 81 | "cancelableQuantity": 0, 82 | "unitPrice": { 83 | "value": "399.00", 84 | "currency": "EUR" 85 | }, 86 | "vatRate": "21.00", 87 | "vatAmount": { 88 | "value": "121.14", 89 | "currency": "EUR" 90 | }, 91 | "discountAmount": { 92 | "value": "100.00", 93 | "currency": "EUR" 94 | }, 95 | "totalAmount": { 96 | "value": "698.00", 97 | "currency": "EUR" 98 | }, 99 | "createdAt": "2018-08-02T09:29:56+00:00", 100 | "_links": { 101 | "productUrl": { 102 | "href": "https://shop.lego.com/nl-NL/Bugatti-Chiron-42083", 103 | "type": "text/html" 104 | }, 105 | "imageUrl": { 106 | "href": "https://sh-s7-live-s.legocdn.com/is/image//LEGO/42083_alt1?$main$", 107 | "type": "text/html" 108 | } 109 | } 110 | }, 111 | { 112 | "resource": "orderline", 113 | "id": "odl_jp31jz", 114 | "orderId": "ord_pbjz8x", 115 | "name": "LEGO 42056 Porsche 911 GT3 RS", 116 | "sku": "5702015594028", 117 | "type": "physical", 118 | "status": "created", 119 | "isCancelable": false, 120 | "quantity": 1, 121 | "quantityShipped": 0, 122 | "amountShipped": { 123 | "value": "0.00", 124 | "currency": "EUR" 125 | }, 126 | "quantityRefunded": 0, 127 | "amountRefunded": { 128 | "value": "0.00", 129 | "currency": "EUR" 130 | }, 131 | "quantityCanceled": 0, 132 | "amountCanceled": { 133 | "value": "0.00", 134 | "currency": "EUR" 135 | }, 136 | "shippableQuantity": 0, 137 | "refundableQuantity": 0, 138 | "cancelableQuantity": 0, 139 | "unitPrice": { 140 | "value": "329.99", 141 | "currency": "EUR" 142 | }, 143 | "vatRate": "21.00", 144 | "vatAmount": { 145 | "value": "57.27", 146 | "currency": "EUR" 147 | }, 148 | "totalAmount": { 149 | "value": "329.99", 150 | "currency": "EUR" 151 | }, 152 | "createdAt": "2018-08-02T09:29:56+00:00", 153 | "_links": { 154 | "productUrl": { 155 | "href": "https://shop.lego.com/nl-NL/Porsche-911-GT3-RS-42056", 156 | "type": "text/html" 157 | }, 158 | "imageUrl": { 159 | "href": "https://sh-s7-live-s.legocdn.com/is/image/LEGO/42056?$PDPDefault$", 160 | "type": "text/html" 161 | } 162 | } 163 | } 164 | ], 165 | "_links": { 166 | "self": { 167 | "href": "https://api.mollie.com/v2/orders/ord_pbjz8x", 168 | "type": "application/hal+json" 169 | }, 170 | "checkout": { 171 | "href": "https://www.mollie.com/payscreen/order/checkout/pbjz8x", 172 | "type": "text/html" 173 | }, 174 | "documentation": { 175 | "href": "https://docs.mollie.com/reference/v2/orders-api/get-order", 176 | "type": "text/html" 177 | } 178 | } 179 | } -------------------------------------------------------------------------------- /tests/Mock/CreateShipmentSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 201 Created 2 | Content-Type: application/hal+json 3 | 4 | { 5 | "resource": "shipment", 6 | "id": "shp_3wmsgCJN4U", 7 | "orderId": "ord_kEn1PlbGa", 8 | "createdAt": "2018-08-09T14:33:54+00:00", 9 | "tracking": { 10 | "carrier": "PostNL", 11 | "code": "3SKABA000000000", 12 | "url": "http://postnl.nl/tracktrace/?B=3SKABA000000000&P=1016EE&D=NL&T=C" 13 | }, 14 | "lines": [ 15 | { 16 | "resource": "orderline", 17 | "id": "odl_dgtxyl", 18 | "orderId": "ord_pbjz8x", 19 | "name": "LEGO 42083 Bugatti Chiron", 20 | "sku": "5702016116977", 21 | "type": "physical", 22 | "status": "shipping", 23 | "isCancelable": true, 24 | "quantity": 1, 25 | "unitPrice": { 26 | "value": "399.00", 27 | "currency": "EUR" 28 | }, 29 | "vatRate": "21.00", 30 | "vatAmount": { 31 | "value": "51.89", 32 | "currency": "EUR" 33 | }, 34 | "discountAmount": { 35 | "value": "100.00", 36 | "currency": "EUR" 37 | }, 38 | "totalAmount": { 39 | "value": "299.00", 40 | "currency": "EUR" 41 | }, 42 | "createdAt": "2018-08-02T09:29:56+00:00", 43 | "_links": { 44 | "productUrl": { 45 | "href": "https://shop.lego.com/nl-NL/Bugatti-Chiron-42083", 46 | "type": "text/html" 47 | }, 48 | "imageUrl": { 49 | "href": "https://sh-s7-live-s.legocdn.com/is/image//LEGO/42083_alt1?$main$", 50 | "type": "text/html" 51 | } 52 | } 53 | }, 54 | { 55 | "resource": "orderline", 56 | "id": "odl_jp31jz", 57 | "orderId": "ord_pbjz8x", 58 | "name": "LEGO 42056 Porsche 911 GT3 RS", 59 | "sku": "5702015594028", 60 | "type": "physical", 61 | "status": "completed", 62 | "isCancelable": false, 63 | "quantity": 1, 64 | "unitPrice": { 65 | "value": "329.99", 66 | "currency": "EUR" 67 | }, 68 | "vatRate": "21.00", 69 | "vatAmount": { 70 | "value": "57.27", 71 | "currency": "EUR" 72 | }, 73 | "totalAmount": { 74 | "value": "329.99", 75 | "currency": "EUR" 76 | }, 77 | "createdAt": "2018-08-02T09:29:56+00:00", 78 | "_links": { 79 | "productUrl": { 80 | "href": "https://shop.lego.com/nl-NL/Porsche-911-GT3-RS-42056", 81 | "type": "text/html" 82 | }, 83 | "imageUrl": { 84 | "href": "https://sh-s7-live-s.legocdn.com/is/image/LEGO/42056?$PDPDefault$", 85 | "type": "text/html" 86 | } 87 | } 88 | } 89 | ], 90 | "_links": { 91 | "self": { 92 | "href": "https://api.mollie.com/v2/order/ord_kEn1PlbGa/shipments/shp_3wmsgCJN4U", 93 | "type": "application/hal+json" 94 | }, 95 | "order": { 96 | "href": "https://api.mollie.com/v2/orders/ord_kEn1PlbGa", 97 | "type": "application/hal+json" 98 | }, 99 | "documentation": { 100 | "href": "https://docs.mollie.com/reference/v2/shipments-api/get-shipment", 101 | "type": "text/html" 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /tests/Mock/FetchCustomerFailure.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 404 Not Found 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "status": 404, 6 | "title": "Not Found", 7 | "detail": "No customer exists with token cst_6HUkmjwzBBa.", 8 | "_links": { 9 | "documentation": { 10 | "href": "https://docs.mollie.com/guides/handling-errors", 11 | "type": "text/html" 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /tests/Mock/FetchCustomerMandatesFailure.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 404 Not Found 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "status": 404, 6 | "title": "Not Found", 7 | "detail": "No customer exists with token cst_6HUkmjwzBBa.", 8 | "_links": { 9 | "documentation": { 10 | "href": "https://docs.mollie.com/guides/handling-errors", 11 | "type": "text/html" 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /tests/Mock/FetchCustomerMandatesSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "count": 5, 6 | "_embedded": { 7 | "mandates": [ 8 | { 9 | "resource": "mandate", 10 | "id": "mdt_AcQl5fdL4h", 11 | "mode": "test", 12 | "status": "valid", 13 | "method": "directdebit", 14 | "details": { 15 | "consumerName": "John Doe", 16 | "consumerAccount": "NL55INGB0000000000", 17 | "consumerBic": "INGBNL2A" 18 | }, 19 | "mandateReference": null, 20 | "signatureDate": "2018-05-07", 21 | "createdAt": "2018-05-07T10:49:08+00:00", 22 | "_links": { 23 | "self": { 24 | "href": "https://api.mollie.com/v2/customers/cst_8wmqcHMN4U/mandates/mdt_AcQl5fdL4h", 25 | "type": "application/hal+json" 26 | }, 27 | "customer": { 28 | "href": "https://api.mollie.com/v2/customers/cst_8wmqcHMN4U", 29 | "type": "application/hal+json" 30 | }, 31 | "documentation": { 32 | "href": "https://mollie.com/en/docs/reference/customers/create-mandate", 33 | "type": "text/html" 34 | } 35 | } 36 | }, 37 | { }, 38 | { }, 39 | { }, 40 | { } 41 | ] 42 | }, 43 | "_links": { 44 | "self": { 45 | "href": "https://api.mollie.com/v2/customers/cst_8wmqcHMN4U/mandates?limit=5", 46 | "type": "application/hal+json" 47 | }, 48 | "previous": null, 49 | "next": { 50 | "href": "https://api.mollie.com/v2/customers/cst_8wmqcHMN4U/mandates?from=mdt_AcQl5fdL4h&limit=5", 51 | "type": "application/hal+json" 52 | }, 53 | "documentation": { 54 | "href": "https://docs.mollie.com/reference/v2/mandates-api/revoke-mandate", 55 | "type": "text/html" 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /tests/Mock/FetchCustomerSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "resource": "customer", 6 | "id": "cst_bSNBBJBzdG", 7 | "mode": "test", 8 | "name": "John Doe", 9 | "email": "john@doe.com", 10 | "locale": "nl_NL", 11 | "metadata": null, 12 | "createdAt": "2018-07-19T12:58:47+00:00", 13 | "_links": { 14 | "self": { 15 | "href": "https://api.mollie.com/v2/customers/cst_6HUkmjwzBB", 16 | "type": "application/hal+json" 17 | }, 18 | "documentation": { 19 | "href": "https://docs.mollie.com/reference/v2/customers-api/get-customer", 20 | "type": "text/html" 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /tests/Mock/FetchIssuersFailure.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 401 Unauthorized Request 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "status": 401, 6 | "title": "Unauthorized Request", 7 | "detail": "Missing authentication, or failed to authenticate", 8 | "_links": { 9 | "documentation": { 10 | "href": "https://docs.mollie.com/guides/authentication", 11 | "type": "text/html" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/Mock/FetchIssuersSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "resource": "method", 6 | "id": "ideal", 7 | "description": "iDEAL", 8 | "image": { 9 | "size1x": "https://www.mollie.com/images/payscreen/methods/ideal.png", 10 | "size2x": "https://www.mollie.com/images/payscreen/methods/ideal%402x.png" 11 | }, 12 | "issuers": [ 13 | { 14 | "resource": "issuer", 15 | "id": "ideal_ABNANL2A", 16 | "name": "ABN AMRO", 17 | "image": { 18 | "size1x": "https://www.mollie.com/images/checkout/v2/ideal-issuer-icons/ABNANL2A.png", 19 | "size2x": "https://www.mollie.com/images/checkout/v2/ideal-issuer-icons/ABNANL2A.png" 20 | } 21 | }, 22 | { 23 | "resource": "issuer", 24 | "id": "ideal_ASNBNL21", 25 | "name": "ASN Bank", 26 | "image": { 27 | "size1x": "https://www.mollie.com/images/checkout/v2/ideal-issuer-icons/ASNBNL21.png", 28 | "size2x": "https://www.mollie.com/images/checkout/v2/ideal-issuer-icons/ASNBNL21.png" 29 | } 30 | } 31 | ], 32 | "_links": { 33 | "self": { 34 | "href": "https://api.mollie.com/v2/methods/ideal", 35 | "type": "application/hal+json" 36 | }, 37 | "documentation": { 38 | "href": "https://docs.mollie.com/reference/v2/methods-api/get-method", 39 | "type": "text/html" 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/Mock/FetchOrderSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Content-Type: application/hal+json 3 | 4 | { 5 | "resource": "order", 6 | "id": "ord_kEn1PlbGa", 7 | "profileId": "pfl_URR55HPMGx", 8 | "method": "ideal", 9 | "amount": { 10 | "value": "1027.99", 11 | "currency": "EUR" 12 | }, 13 | "status": "created", 14 | "isCancelable": true, 15 | "metadata": null, 16 | "createdAt": "2018-08-02T09:29:56+00:00", 17 | "expiresAt": "2018-08-30T09:29:56+00:00", 18 | "mode": "live", 19 | "locale": "nl_NL", 20 | "billingAddress": { 21 | "organizationName": "Mollie B.V.", 22 | "streetAndNumber": "Keizersgracht 313", 23 | "postalCode": "1016 EE", 24 | "city": "Amsterdam", 25 | "country": "nl", 26 | "givenName": "Luke", 27 | "familyName": "Skywalker", 28 | "email": "luke@skywalker.com" 29 | }, 30 | "orderNumber": "18475", 31 | "shippingAddress": { 32 | "organizationName": "Mollie B.V.", 33 | "streetAndNumber": "Keizersgracht 313", 34 | "postalCode": "1016 EE", 35 | "city": "Amsterdam", 36 | "country": "nl", 37 | "givenName": "Luke", 38 | "familyName": "Skywalker", 39 | "email": "luke@skywalker.com" 40 | }, 41 | "redirectUrl": "https://example.org/redirect", 42 | "lines": [ 43 | { 44 | "resource": "orderline", 45 | "id": "odl_dgtxyl", 46 | "orderId": "ord_pbjz8x", 47 | "name": "LEGO 42083 Bugatti Chiron", 48 | "sku": "5702016116977", 49 | "type": "physical", 50 | "status": "created", 51 | "isCancelable": false, 52 | "quantity": 2, 53 | "quantityShipped": 0, 54 | "amountShipped": { 55 | "value": "0.00", 56 | "currency": "EUR" 57 | }, 58 | "quantityRefunded": 0, 59 | "amountRefunded": { 60 | "value": "0.00", 61 | "currency": "EUR" 62 | }, 63 | "quantityCanceled": 0, 64 | "amountCanceled": { 65 | "value": "0.00", 66 | "currency": "EUR" 67 | }, 68 | "shippableQuantity": 0, 69 | "refundableQuantity": 0, 70 | "cancelableQuantity": 0, 71 | "unitPrice": { 72 | "value": "399.00", 73 | "currency": "EUR" 74 | }, 75 | "vatRate": "21.00", 76 | "vatAmount": { 77 | "value": "121.14", 78 | "currency": "EUR" 79 | }, 80 | "discountAmount": { 81 | "value": "100.00", 82 | "currency": "EUR" 83 | }, 84 | "totalAmount": { 85 | "value": "698.00", 86 | "currency": "EUR" 87 | }, 88 | "createdAt": "2018-08-02T09:29:56+00:00", 89 | "_links": { 90 | "productUrl": { 91 | "href": "https://shop.lego.com/nl-NL/Bugatti-Chiron-42083", 92 | "type": "text/html" 93 | }, 94 | "imageUrl": { 95 | "href": "https://sh-s7-live-s.legocdn.com/is/image//LEGO/42083_alt1?$main$", 96 | "type": "text/html" 97 | } 98 | } 99 | }, 100 | { 101 | "resource": "orderline", 102 | "id": "odl_jp31jz", 103 | "orderId": "ord_pbjz8x", 104 | "name": "LEGO 42056 Porsche 911 GT3 RS", 105 | "sku": "5702015594028", 106 | "type": "physical", 107 | "status": "created", 108 | "isCancelable": false, 109 | "quantity": 1, 110 | "quantityShipped": 0, 111 | "amountShipped": { 112 | "value": "0.00", 113 | "currency": "EUR" 114 | }, 115 | "quantityRefunded": 0, 116 | "amountRefunded": { 117 | "value": "0.00", 118 | "currency": "EUR" 119 | }, 120 | "quantityCanceled": 0, 121 | "amountCanceled": { 122 | "value": "0.00", 123 | "currency": "EUR" 124 | }, 125 | "shippableQuantity": 0, 126 | "refundableQuantity": 0, 127 | "cancelableQuantity": 0, 128 | "unitPrice": { 129 | "value": "329.99", 130 | "currency": "EUR" 131 | }, 132 | "vatRate": "21.00", 133 | "vatAmount": { 134 | "value": "57.27", 135 | "currency": "EUR" 136 | }, 137 | "totalAmount": { 138 | "value": "329.99", 139 | "currency": "EUR" 140 | }, 141 | "createdAt": "2018-08-02T09:29:56+00:00", 142 | "_links": { 143 | "productUrl": { 144 | "href": "https://shop.lego.com/nl-NL/Porsche-911-GT3-RS-42056", 145 | "type": "text/html" 146 | }, 147 | "imageUrl": { 148 | "href": "https://sh-s7-live-s.legocdn.com/is/image/LEGO/42056?$PDPDefault$", 149 | "type": "text/html" 150 | } 151 | } 152 | } 153 | ], 154 | "_embedded": { 155 | "payments": [ 156 | { 157 | "resource": "payment", 158 | "id": "tr_ncaPcAhuUV", 159 | "mode": "live", 160 | "createdAt": "2018-09-07T12:00:05+00:00", 161 | "amount": { 162 | "value": "1027.99", 163 | "currency": "EUR" 164 | }, 165 | "description": "Order #1337 (Lego cars)", 166 | "method": null, 167 | "metadata": null, 168 | "status": "open", 169 | "isCancelable": false, 170 | "locale": "nl_NL", 171 | "profileId": "pfl_URR55HPMGx", 172 | "orderId": "ord_kEn1PlbGa", 173 | "sequenceType": "oneoff", 174 | "redirectUrl": "https://example.org/redirect", 175 | "_links": { 176 | "self": { 177 | "href": "https://api.mollie.com/v2/payments/tr_ncaPcAhuUV", 178 | "type": "application/hal+json" 179 | }, 180 | "checkout": { 181 | "href": "https://www.mollie.com/payscreen/select-method/ncaPcAhuUV", 182 | "type": "text/html" 183 | }, 184 | "order": { 185 | "href": "https://api.mollie.com/v2/orders/ord_kEn1PlbGa", 186 | "type": "application/hal+json" 187 | } 188 | } 189 | } 190 | ] 191 | }, 192 | "_links": { 193 | "self": { 194 | "href": "https://api.mollie.com/v2/orders/ord_pbjz8x", 195 | "type": "application/hal+json" 196 | }, 197 | "checkout": { 198 | "href": "https://www.mollie.com/payscreen/order/checkout/pbjz8x", 199 | "type": "text/html" 200 | }, 201 | "documentation": { 202 | "href": "https://docs.mollie.com/reference/v2/orders-api/get-order", 203 | "type": "text/html" 204 | } 205 | } 206 | } -------------------------------------------------------------------------------- /tests/Mock/FetchPaymentMethodsFailure.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 401 Unauthorized Request 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "status": 401, 6 | "title": "Unauthorized Request", 7 | "detail": "Missing authentication, or failed to authenticate", 8 | "_links": { 9 | "documentation": { 10 | "href": "https://docs.mollie.com/guides/authentication", 11 | "type": "text/html" 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /tests/Mock/FetchPaymentMethodsSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "_embedded": { 6 | "methods": [ 7 | { 8 | "resource": "method", 9 | "id": "ideal", 10 | "description": "iDEAL", 11 | "image": { 12 | "size1x": "https://www.mollie.com/images/payscreen/methods/ideal.png", 13 | "size2x": "https://www.mollie.com/images/payscreen/methods/ideal%402x.png" 14 | }, 15 | "_links": { 16 | "self": { 17 | "href": "https://api.mollie.com/v2/methods/ideal", 18 | "type": "application/hal+json" 19 | } 20 | } 21 | }, 22 | { 23 | "resource": "method", 24 | "id": "creditcard", 25 | "description": "Credit card", 26 | "image": { 27 | "size1x": "https://www.mollie.com/images/payscreen/methods/creditcard.png", 28 | "size2x": "https://www.mollie.com/images/payscreen/methods/creditcard%402x.png" 29 | }, 30 | "_links": { 31 | "self": { 32 | "href": "https://api.mollie.com/v2/methods/creditcard", 33 | "type": "application/hal+json" 34 | } 35 | } 36 | }, 37 | { 38 | "resource": "method", 39 | "id": "paypal", 40 | "description": "PayPal", 41 | "image": { 42 | "size1x": "https://www.mollie.com/images/payscreen/methods/paypal.png", 43 | "size2x": "https://www.mollie.com/images/payscreen/methods/paypal%402x.png" 44 | }, 45 | "_links": { 46 | "self": { 47 | "href": "https://api.mollie.com/v2/methods/paypal", 48 | "type": "application/hal+json" 49 | } 50 | } 51 | }, 52 | { 53 | "resource": "method", 54 | "id": "bancontact", 55 | "description": "Bancontact", 56 | "image": { 57 | "size1x": "https://www.mollie.com/images/payscreen/methods/mistercash.png", 58 | "size2x": "https://www.mollie.com/images/payscreen/methods/mistercash%402x.png" 59 | }, 60 | "_links": { 61 | "self": { 62 | "href": "https://api.mollie.com/v2/methods/mistercash", 63 | "type": "application/hal+json" 64 | } 65 | } 66 | }, 67 | { 68 | "resource": "method", 69 | "id": "banktransfer", 70 | "description": "Bank transfer", 71 | "image": { 72 | "size1x": "https://www.mollie.com/images/payscreen/methods/banktransfer.png", 73 | "size2x": "https://www.mollie.com/images/payscreen/methods/banktransfer%402x.png" 74 | }, 75 | "_links": { 76 | "self": { 77 | "href": "https://api.mollie.com/v2/methods/banktransfer", 78 | "type": "application/hal+json" 79 | } 80 | } 81 | }, 82 | { 83 | "resource": "method", 84 | "id": "sofort", 85 | "description": "SOFORT Banking", 86 | "image": { 87 | "size1x": "https://www.mollie.com/images/payscreen/methods/sofort.png", 88 | "size2x": "https://www.mollie.com/images/payscreen/methods/sofort%402x.png" 89 | }, 90 | "_links": { 91 | "self": { 92 | "href": "https://api.mollie.com/v2/methods/sofort", 93 | "type": "application/hal+json" 94 | } 95 | } 96 | }, 97 | { 98 | "resource": "method", 99 | "id": "eps", 100 | "description": "eps", 101 | "image": { 102 | "size1x": "https://www.mollie.com/images/payscreen/methods/eps.png", 103 | "size2x": "https://www.mollie.com/images/payscreen/methods/eps%402x.png" 104 | }, 105 | "_links": { 106 | "self": { 107 | "href": "https://api.mollie.com/v2/methods/eps", 108 | "type": "application/hal+json" 109 | } 110 | } 111 | }, 112 | { 113 | "resource": "method", 114 | "id": "giropay", 115 | "description": "Giropay", 116 | "image": { 117 | "size1x": "https://www.mollie.com/images/payscreen/methods/giropay.png", 118 | "size2x": "https://www.mollie.com/images/payscreen/methods/giropay%402x.png" 119 | }, 120 | "_links": { 121 | "self": { 122 | "href": "https://api.mollie.com/v2/methods/giropay", 123 | "type": "application/hal+json" 124 | } 125 | } 126 | }, 127 | { 128 | "resource": "method", 129 | "id": "kbc", 130 | "description": "KBC/CBC Payment Button", 131 | "image": { 132 | "size1x": "https://www.mollie.com/images/payscreen/methods/kbc.png", 133 | "size2x": "https://www.mollie.com/images/payscreen/methods/kbc%402x.png" 134 | }, 135 | "_links": { 136 | "self": { 137 | "href": "https://api.mollie.com/v2/methods/kbc", 138 | "type": "application/hal+json" 139 | } 140 | } 141 | }, 142 | { 143 | "resource": "method", 144 | "id": "belfius", 145 | "description": "Belfius Pay Button", 146 | "image": { 147 | "size1x": "https://www.mollie.com/images/payscreen/methods/belfius.png", 148 | "size2x": "https://www.mollie.com/images/payscreen/methods/belfius%402x.png" 149 | }, 150 | "_links": { 151 | "self": { 152 | "href": "https://api.mollie.com/v2/methods/belfius", 153 | "type": "application/hal+json" 154 | } 155 | } 156 | }, 157 | { 158 | "resource": "method", 159 | "id": "inghomepay", 160 | "description": "ING Home'Pay", 161 | "image": { 162 | "size1x": "https://www.mollie.com/images/payscreen/methods/inghomepay.png", 163 | "size2x": "https://www.mollie.com/images/payscreen/methods/inghomepay%402x.png" 164 | }, 165 | "_links": { 166 | "self": { 167 | "href": "https://api.mollie.com/v2/methods/inghomepay", 168 | "type": "application/hal+json" 169 | } 170 | } 171 | }, 172 | { 173 | "resource": "method", 174 | "id": "bitcoin", 175 | "description": "Bitcoin", 176 | "image": { 177 | "size1x": "https://www.mollie.com/images/payscreen/methods/bitcoin.png", 178 | "size2x": "https://www.mollie.com/images/payscreen/methods/bitcoin%402x.png" 179 | }, 180 | "_links": { 181 | "self": { 182 | "href": "https://api.mollie.com/v2/methods/bitcoin", 183 | "type": "application/hal+json" 184 | } 185 | } 186 | } 187 | ] 188 | }, 189 | "count": 12, 190 | "_links": { 191 | "documentation": { 192 | "href": "https://docs.mollie.com/reference/v2/methods-api/list-methods", 193 | "type": "text/html" 194 | }, 195 | "self": { 196 | "href": "https://api.mollie.nl/v2/methods", 197 | "type": "application/hal+json" 198 | } 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /tests/Mock/FetchTransaction404Failure.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 404 Not Found 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "status": 404, 6 | "title": "Not Found", 7 | "detail": "No transaction exists with token tr_Qzin4iTWrU.", 8 | "_links": { 9 | "documentation": { 10 | "href": "https://docs.mollie.com/guides/handling-errors", 11 | "type": "text/html" 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /tests/Mock/FetchTransactionExpired.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Content-Type: application/json; charset=utf-8 3 | 4 | { 5 | "resource": "payment", 6 | "id": "tr_WDqYK6vllg", 7 | "mode": "test", 8 | "createdAt": "2018-03-12T10:56:15+00:00", 9 | "amount": { 10 | "value": "1.00", 11 | "currency": "EUR" 12 | }, 13 | "description": "Order 66", 14 | "method": null, 15 | "metadata": null, 16 | "status": "expired", 17 | "isCancelable": false, 18 | "expiresAt": "2018-03-12T11:11:15+00:00", 19 | "details": null, 20 | "profileId": "pfl_7N5qjbu42V", 21 | "sequenceType": "oneoff", 22 | "redirectUrl": "https://www.example.org/payment/completed", 23 | "_links": { 24 | "self": { 25 | "href": "https://api.mollie.com/v2/payments/tr_WDqYK6vllg" 26 | }, 27 | "checkout": { 28 | "href": "https://www.mollie.com/payscreen/select-method/PSj7b45bkj" 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /tests/Mock/FetchTransactionSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "resource": "payment", 6 | "id": "tr_WDqYK6vllg", 7 | "mode": "test", 8 | "createdAt": "2018-03-20T13:13:37+00:00", 9 | "amount": { 10 | "value": "10.00", 11 | "currency": "EUR" 12 | }, 13 | "description": "My first payment", 14 | "method": null, 15 | "metadata": { 16 | "order_id": "12345" 17 | }, 18 | "status": "paid", 19 | "isCancelable": false, 20 | "expiresAt": "2018-03-20T13:28:37+00:00", 21 | "details": null, 22 | "profileId": "pfl_QkEhN94Ba", 23 | "sequenceType": "oneoff", 24 | "redirectUrl": "https://webshop.example.org/order/12345/", 25 | "webhookUrl": "https://webshop.example.org/payments/webhook/", 26 | "_links": { 27 | "self": { 28 | "href": "https://api.mollie.com/v2/payments/tr_WDqYK6vllg", 29 | "type": "application/hal+json" 30 | }, 31 | "checkout": { 32 | "href": "https://www.mollie.com/payscreen/select-method/WDqYK6vllg", 33 | "type": "text/html" 34 | }, 35 | "documentation": { 36 | "href": "https://docs.mollie.com/reference/v2/payments-api/get-payment", 37 | "type": "text/html" 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /tests/Mock/PurchaseIssuerFailure.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 422 Unprocessable Entity 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "status": 422, 6 | "title": "Unprocessable Entity", 7 | "detail": "The payment method is invalid", 8 | "field": "method", 9 | "_links": { 10 | "documentation": { 11 | "href": "https://docs.mollie.com/guides/handling-errors", 12 | "type": "text/html" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/Mock/PurchaseSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 201 Created 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "resource": "payment", 6 | "id": "tr_7UhSN1zuXS", 7 | "mode": "test", 8 | "createdAt": "2018-03-20T09:13:37+00:00", 9 | "amount": { 10 | "value": "10.00", 11 | "currency": "EUR" 12 | }, 13 | "description": "My first payment", 14 | "method": null, 15 | "metadata": { 16 | "order_id": "12345" 17 | }, 18 | "status": "open", 19 | "isCancelable": false, 20 | "expiresAt": "2018-03-20T09:28:37+00:00", 21 | "details": null, 22 | "profileId": "pfl_QkEhN94Ba", 23 | "sequenceType": "oneoff", 24 | "redirectUrl": "https://webshop.example.org/order/12345/", 25 | "webhookUrl": "https://webshop.example.org/payments/webhook/", 26 | "_links": { 27 | "self": { 28 | "href": "https://api.mollie.com/v2/payments/tr_7UhSN1zuXS", 29 | "type": "application/json" 30 | }, 31 | "checkout": { 32 | "href": "https://www.mollie.com/payscreen/select-method/7UhSN1zuXS", 33 | "type": "text/html" 34 | }, 35 | "documentation": { 36 | "href": "https://docs.mollie.com/reference/v2/payments-api/create-payment", 37 | "type": "text/html" 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/Mock/Refund401Failure.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 401 Authorization Required 2 | Server: nginx/1.4.4 3 | Date: Mon, 20 Jan 2014 10:04:18 GMT 4 | Content-Type: application/json; charset=utf-8 5 | Content-Length: 155 6 | Connection: keep-alive 7 | Access-Control-Allow-Credentials: true 8 | Access-Control-Allow-Methods: GET, POST, HEAD, OPTIONS, DELETE 9 | Access-Control-Max-Age: 300 10 | Cache-Control: no-cache, no-store 11 | Strict-Transport-Security: max-age=31556926; includeSubDomains 12 | Www-Authenticate: Basic realm="Mollie API Key" 13 | 14 | { 15 | "status": 401, 16 | "title": "Unauthorized Request", 17 | "detail": "Missing authentication, or failed to authenticate", 18 | "_links": { 19 | "documentation": { 20 | "href": "https://docs.mollie.com/guides/authentication", 21 | "type": "text/html" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/Mock/Refund422Failure.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 422 Unprocessable Entity 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "status": 422, 6 | "title": "Unprocessable Entity", 7 | "detail": "The payment method is invalid", 8 | "field": "method", 9 | "_links": { 10 | "documentation": { 11 | "href": "https://docs.mollie.com/guides/handling-errors", 12 | "type": "text/html" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/Mock/RefundSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 201 Created 2 | Server: nginx/1.4.4 3 | Date: Sun, 19 Jan 2014 11:41:55 GMT 4 | Content-Type: application/json; charset=utf-8 5 | Content-Length: 344 6 | Connection: keep-alive 7 | Access-Control-Allow-Credentials: true 8 | Access-Control-Allow-Methods: GET, POST, HEAD, OPTIONS, DELETE 9 | Access-Control-Max-Age: 300 10 | Cache-Control: no-cache, no-store 11 | Strict-Transport-Security: max-age=31556926; includeSubDomains 12 | X-Whom: dc1-web-2 13 | 14 | { 15 | "resource": "refund", 16 | "id": "re_4qqhO89gsT", 17 | "amount": { 18 | "currency": "EUR", 19 | "value": "5.95" 20 | }, 21 | "status": "pending", 22 | "createdAt": "2018-03-14T17:09:02.0Z", 23 | "description": "Order", 24 | "paymentId": "tr_WDqYK6vllg", 25 | "_links": { 26 | "self": { 27 | "href": "https://api.mollie.com/v2/payments/tr_WDqYK6vllg/refunds/re_4qqhO89gsT", 28 | "type": "application/hal+json" 29 | }, 30 | "payment": { 31 | "href": "https://api.mollie.com/v2/payments/tr_WDqYK6vllg", 32 | "type": "application/hal+json" 33 | }, 34 | "documentation": { 35 | "href": "https://docs.mollie.com/reference/v2/refunds-api/create-refund", 36 | "type": "text/html" 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /tests/Mock/RevokeCustomerMandateSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 204 No Content 2 | 3 | -------------------------------------------------------------------------------- /tests/Mock/UpdateCustomerFailure.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 401 Unauthorized Request 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "status": 401, 6 | "title": "Unauthorized Request", 7 | "detail": "Missing authentication, or failed to authenticate", 8 | "_links": { 9 | "documentation": { 10 | "href": "https://docs.mollie.com/guides/authentication", 11 | "type": "text/html" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/Mock/UpdateCustomerSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Content-Type: application/hal+json; charset=utf-8 3 | 4 | { 5 | "resource": "customer", 6 | "id": "cst_bSNBBJBzdG", 7 | "mode": "test", 8 | "name": "Jane Doe", 9 | "email": "john@doe.com", 10 | "locale": "nl_NL", 11 | "metadata": "Just some meta data.", 12 | "createdAt": "2018-07-19T12:58:47+00:00", 13 | "_links": { 14 | "self": { 15 | "href": "https://api.mollie.com/v2/customers/cst_6HUkmjwzBB", 16 | "type": "application/hal+json" 17 | }, 18 | "documentation": { 19 | "href": "https://docs.mollie.com/reference/v2/customers-api/update-customer", 20 | "type": "text/html" 21 | } 22 | } 23 | } --------------------------------------------------------------------------------