├── .babelrc ├── .editorconfig ├── .env.example ├── .eslintrc ├── .github ├── codeql-configuration.yml └── workflows │ ├── codeql.yml │ └── test.yml ├── .gitignore ├── .prettierrc ├── CHANGELOG.md ├── LICENSE ├── MIGRATION.md ├── Makefile ├── README.md ├── examples ├── .eslintrc ├── chargebacks │ ├── get.js │ ├── get.ts │ ├── list.js │ └── list.ts ├── customers │ ├── create-payment-with-mandate.js │ ├── create-payment-with-mandate.ts │ ├── create-recurring-payment.js │ ├── create-recurring-payment.ts │ ├── create.js │ ├── create.ts │ ├── delete.js │ ├── delete.ts │ ├── get.js │ ├── get.ts │ ├── list-payments.js │ ├── list-payments.ts │ ├── list.js │ ├── list.ts │ ├── update.js │ └── update.ts ├── mandates │ ├── create.js │ ├── create.ts │ ├── get.js │ ├── get.ts │ ├── list.js │ ├── list.ts │ ├── revoke.js │ └── revoke.ts ├── methods │ ├── get-with-issuers.js │ ├── get-with-issuers.ts │ ├── get.js │ ├── get.ts │ ├── list-for-amount-and-currency.js │ ├── list-for-amount-and-currency.ts │ ├── list-with-issuers.js │ ├── list-with-issuers.ts │ ├── list.js │ └── list.ts ├── node_modules │ └── @mollie │ │ └── api-client ├── orders │ ├── cancel.js │ ├── cancel.ts │ ├── create.js │ ├── create.ts │ ├── create_payment.js │ ├── create_payment.ts │ ├── get.js │ ├── get.ts │ ├── list.js │ ├── list.ts │ ├── update.js │ └── update.ts ├── package-lock.json ├── package.json ├── payments │ ├── cancel.js │ ├── cancel.ts │ ├── create.js │ ├── create.ts │ ├── get.js │ ├── get.ts │ ├── release.js │ ├── release.ts │ ├── webhook.js │ └── webhook.ts ├── refunds │ ├── cancel.js │ ├── cancel.ts │ ├── create.js │ ├── create.ts │ ├── get.js │ ├── get.ts │ ├── list.js │ └── list.ts ├── subscriptions │ ├── cancel.js │ ├── cancel.ts │ ├── create.js │ ├── create.ts │ ├── get.js │ ├── get.ts │ ├── list-payments.js │ ├── list-payments.ts │ ├── list.js │ └── list.ts ├── terminals │ ├── get.ts │ └── list.ts └── with-express │ ├── 01-new-payment.js │ ├── 02-webhook-verification.js │ ├── 03-return-page.js │ ├── 04-ideal-payment.js │ ├── 05-payments-history.js │ ├── 06-refund-payment.js │ ├── 07-new-customer.js │ ├── 08-new-customer-payment.js │ ├── 09-customer-payments-history.js │ ├── 10-recurring-first-payment.js │ ├── 11-recurring-payment.js │ └── 16-recurring-subscription.js ├── jest.config.js ├── package.json ├── rollup.config.js ├── src ├── Options.ts ├── binders │ ├── Binder.ts │ ├── applePay │ │ ├── ApplePayBinder.ts │ │ └── parameters.ts │ ├── chargebacks │ │ ├── ChargebacksBinder.ts │ │ └── parameters.ts │ ├── customers │ │ ├── CustomersBinder.ts │ │ ├── mandates │ │ │ ├── CustomerMandatesBinder.ts │ │ │ └── parameters.ts │ │ ├── parameters.ts │ │ ├── payments │ │ │ ├── CustomerPaymentsBinder.ts │ │ │ └── parameters.ts │ │ └── subscriptions │ │ │ ├── CustomerSubscriptionsBinder.ts │ │ │ └── parameters.ts │ ├── methods │ │ ├── MethodsBinder.ts │ │ └── parameters.ts │ ├── onboarding │ │ ├── OnboardingBinder.ts │ │ └── parameters.ts │ ├── orders │ │ ├── OrdersBinder.ts │ │ ├── orderlines │ │ │ ├── OrderLinesBinder.ts │ │ │ └── parameters.ts │ │ ├── parameters.ts │ │ └── shipments │ │ │ ├── OrderShipmentsBinder.ts │ │ │ └── parameters.ts │ ├── organizations │ │ └── OrganizationsBinder.ts │ ├── paymentLinks │ │ ├── PaymentLinksBinder.ts │ │ └── parameters.ts │ ├── payments │ │ ├── PaymentsBinder.ts │ │ ├── captures │ │ │ ├── PaymentCapturesBinder.ts │ │ │ └── parameters.ts │ │ ├── chargebacks │ │ │ ├── PaymentChargebacksBinder.ts │ │ │ └── parameters.ts │ │ ├── orders │ │ │ ├── OrderPaymentsBinder.ts │ │ │ └── parameters.ts │ │ ├── parameters.ts │ │ └── refunds │ │ │ ├── PaymentRefundsBinder.ts │ │ │ └── parameters.ts │ ├── permissions │ │ └── PermissionsBinder.ts │ ├── profiles │ │ ├── ProfilesBinder.ts │ │ ├── giftcardIssuers │ │ │ ├── ProfileGiftcardIssuersBinder.ts │ │ │ └── parameters.ts │ │ ├── methods │ │ │ ├── ProfileMethodsBinder.ts │ │ │ └── parameters.ts │ │ ├── parameters.ts │ │ └── voucherIssuers │ │ │ ├── ProfileVoucherIssuersBinder.ts │ │ │ └── parameters.ts │ ├── refunds │ │ ├── RefundsBinder.ts │ │ ├── orders │ │ │ ├── OrderRefundsBinder.ts │ │ │ └── parameters.ts │ │ └── parameters.ts │ ├── settlements │ │ ├── SettlementsBinder.ts │ │ ├── captures │ │ │ ├── SettlementCapturesBinder.ts │ │ │ └── parameters.ts │ │ ├── chargebacks │ │ │ ├── SettlementChargebacksBinder.ts │ │ │ └── parameters.ts │ │ ├── parameters.ts │ │ ├── payments │ │ │ ├── SettlementPaymentsBinder.ts │ │ │ └── parameters.ts │ │ └── refunds │ │ │ ├── SettlementRefundsBinder.ts │ │ │ └── parameters.ts │ ├── subscriptions │ │ ├── SubscriptionsBinder.ts │ │ ├── parameters.ts │ │ └── payments │ │ │ ├── SubscriptionPaymentsBinder.ts │ │ │ └── parameters.ts │ └── terminals │ │ ├── TerminalsBinder.ts │ │ └── parameters.ts ├── cacert.pem ├── certs.d.ts ├── communication │ ├── NetworkClient.ts │ ├── TransformingNetworkClient.ts │ ├── breakUrl.ts │ ├── buildUrl.ts │ ├── dromedaryCase.ts │ └── makeRetrying.ts ├── createMollieClient.ts ├── data │ ├── Helper.ts │ ├── Issuer.ts │ ├── Model.ts │ ├── applePaySession │ │ └── ApplePaySession.ts │ ├── chargebacks │ │ ├── Chargeback.ts │ │ └── ChargebackHelper.ts │ ├── customers │ │ ├── Customer.ts │ │ ├── CustomerHelper.ts │ │ └── mandates │ │ │ ├── Mandate.ts │ │ │ ├── MandateHelper.ts │ │ │ └── data.ts │ ├── global.ts │ ├── issuer │ │ └── IssuerModel.ts │ ├── methods │ │ ├── Method.ts │ │ ├── MethodHelper.ts │ │ └── data.ts │ ├── onboarding │ │ ├── Onboarding.ts │ │ ├── OnboardingHelper.ts │ │ └── data.ts │ ├── orders │ │ ├── Order.ts │ │ ├── OrderHelper.ts │ │ ├── data.ts │ │ ├── orderlines │ │ │ └── OrderLine.ts │ │ └── shipments │ │ │ ├── Shipment.ts │ │ │ └── ShipmentHelper.ts │ ├── organizations │ │ └── Organizations.ts │ ├── page │ │ └── Page.ts │ ├── paymentLinks │ │ ├── PaymentLink.ts │ │ ├── PaymentLinkHelper.ts │ │ └── data.ts │ ├── payments │ │ ├── Payment.ts │ │ ├── PaymentHelper.ts │ │ ├── captures │ │ │ ├── Capture.ts │ │ │ ├── CaptureHelper.ts │ │ │ └── data.ts │ │ └── data.ts │ ├── permissions │ │ └── Permission.ts │ ├── profiles │ │ ├── Profile.ts │ │ ├── ProfileHelper.ts │ │ └── data.ts │ ├── refunds │ │ ├── Refund.ts │ │ ├── RefundHelper.ts │ │ └── data.ts │ ├── settlements │ │ ├── SettlementHelper.ts │ │ ├── SettlementModel.ts │ │ └── data.ts │ ├── subscriptions │ │ ├── Subscription.ts │ │ ├── SubscriptionHelper.ts │ │ └── data.ts │ └── terminals │ │ ├── Terminal.ts │ │ └── data.ts ├── errors │ └── ApiError.ts ├── plumbing │ ├── Throttler.ts │ ├── alias.ts │ ├── assertWellFormedId.ts │ ├── buildFromEntries.ts │ ├── capitalize.ts │ ├── convertToNonNegativeInteger.ts │ ├── fling.ts │ ├── iteration │ │ ├── DemandingIterator.ts │ │ ├── HelpfulIterator.ts │ │ ├── IteratorHelpers.ts │ │ ├── LazyIterator.ts │ │ ├── emptyHelpfulIterator.ts │ │ └── makeAsync.ts │ ├── renege.ts │ ├── resolveIf.ts │ └── undefinedPromise.ts ├── types.ts └── types │ ├── Callback.ts │ ├── Maybe.ts │ ├── MaybeArray.ts │ ├── Nullable.ts │ ├── PickOptional.ts │ ├── PickRequired.ts │ ├── Seal.ts │ ├── Xor.ts │ └── parameters.ts ├── tests ├── .eslintrc ├── NetworkMocker.ts ├── __nock-fixtures__ │ ├── iteration.json │ ├── paymentLinks.json │ └── profiles.json ├── communication │ ├── custom-idempotency-key.test.ts │ └── request-retrying.test.ts ├── getHead.ts ├── integration │ ├── chargebacks.test.ts │ ├── customers.test.ts │ ├── methods.test.ts │ ├── orders.test.ts │ ├── payments.test.ts │ ├── refunds.test.ts │ └── terminals.test.ts ├── iteration │ ├── demanding-iteration.test.ts │ ├── iteration.test.ts │ └── multipage-iteration.test.ts ├── matchers │ ├── observePromise.ts │ ├── toBeDepleted.ts │ └── toStartWith.ts ├── paymentLinks │ └── paymentLinks.test.ts ├── profiles │ └── profiles.test.ts ├── settlements │ └── settlements.test.ts ├── tick.ts └── unit │ ├── __stubs__ │ ├── list │ │ ├── customers_page_1.json │ │ ├── customers_page_2.json │ │ └── customers_page_3.json │ └── methods.json │ ├── backwards-compatibitily.test.ts │ ├── createMollieClient.test.ts │ ├── errors.test.ts │ ├── inspect.test.ts │ ├── models │ ├── onboarding.test.ts │ ├── order.test.ts │ ├── payment.test.ts │ ├── profile.test.ts │ ├── refund.test.ts │ └── subscription.test.ts │ ├── networking.test.ts │ └── resources │ ├── __snapshots__ │ ├── lists.test.ts.snap │ └── methods.test.ts.snap │ ├── applePay.test.ts │ ├── chargebacks.test.ts │ ├── customers.test.ts │ ├── customers │ ├── mandates.test.ts │ ├── payments.test.ts │ └── subscriptions.test.ts │ ├── lists.test.ts │ ├── methods.test.ts │ ├── onboarding.test.ts │ ├── orders.test.ts │ ├── orders │ ├── payments.test.ts │ ├── refunds.test.ts │ └── shipments.test.ts │ ├── organizations.test.ts │ ├── payments.test.ts │ ├── payments │ ├── captures.test.ts │ └── refunds.test.ts │ ├── permissions.test.ts │ ├── profiles.test.ts │ ├── refunds.test.ts │ ├── subscriptions.test.ts │ └── subscriptions │ └── payments.test.ts ├── tsconfig-declarations.json ├── tsconfig.json └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@babel/plugin-proposal-class-properties"], 3 | "presets": [ 4 | "@babel/preset-typescript", 5 | [ 6 | "@babel/preset-env", 7 | { 8 | "targets": { 9 | "node": "6.9" 10 | } 11 | } 12 | ] 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | API_KEY= 2 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "@mollie/typescript" 4 | ], 5 | "rules": { 6 | "// 1": [0, "@typescript-eslint/recommended turns no-unused-vars off, as it does not play nicely with TypeScript. Unfortunately, @mollie/eslint-config-base turns it back on."], 7 | "no-unused-vars": "off", 8 | "// 2": [0, "This rule warns about use of the arguments object, which is used deliberately in this project."], 9 | "prefer-rest-params": "off", 10 | "// 3": [0, "This project uses starred block comments (documentation for external consumption) and line comments (throughout-code clarifications)."], 11 | "multiline-comment-style": ["off"], 12 | "@typescript-eslint/no-unused-vars": ["warn", { "varsIgnorePattern": "^_+$" }] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.github/codeql-configuration.yml: -------------------------------------------------------------------------------- 1 | name: CodeQL Configuration 2 | 3 | paths-ignore: 4 | - './tests' -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: CodeQL 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | # Run on every 1st and 15th of the month. 9 | schedule: 10 | - cron: 0 12 1,15 * * 11 | 12 | jobs: 13 | analyze: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | security-events: write 17 | strategy: 18 | fail-fast: false 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v4 22 | - name: Initialize CodeQL 23 | uses: github/codeql-action/init@v2 24 | with: 25 | config-file: ./.github/codeql-configuration.yml 26 | languages: javascript 27 | - name: Perform CodeQL Analysis 28 | uses: github/codeql-action/analyze@v2 29 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Node.js test 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | node-version: [14.x, 18.x, 20.x] 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | - name: Use Node.js ${{ matrix.node-version }} 19 | uses: actions/setup-node@v4 20 | with: 21 | node-version: ${{ matrix.node-version }} 22 | - name: Install dependencies 23 | run: yarn --frozen-lockfile 24 | - name: Run test suite 25 | run: yarn test 26 | env: 27 | # Set the API key for the integration tests. In the future, all tests will rely on snapshots. An API key will 28 | # then only be required to update those snapshots. The API key can then be removed from this file. 29 | API_KEY: ${{ secrets.TEST_API_KEY }} 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /coverage/ 2 | /dist/ 3 | /node_modules/ 4 | /.idea/ 5 | /.vscode/ 6 | /.env 7 | *.log 8 | /.rpt2*/ 9 | .DS_Store 10 | /mk-ca-bundle.pl 11 | /*.code-workspace -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 200, 3 | "singleQuote": true, 4 | "trailingComma": "all", 5 | "bracketSpacing": true, 6 | "arrowParens": "avoid" 7 | } 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2013-2021, Mollie B.V. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | src/cacert.pem: certdata.txt 2 | mv ca-bundle.crt src/cacert.pem 3 | rm certdata.txt 4 | 5 | mk-ca-bundle.pl: 6 | curl -q https://raw.githubusercontent.com/curl/curl/master/lib/mk-ca-bundle.pl --output mk-ca-bundle.pl 7 | chmod +x mk-ca-bundle.pl 8 | 9 | certdata.txt: mk-ca-bundle.pl 10 | ./mk-ca-bundle.pl 11 | -------------------------------------------------------------------------------- /examples/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "import/no-unresolved": "off", 4 | "import/no-extraneous-dependencies": "off", 5 | "no-unused-vars": "off", 6 | "@typescript-eslint/no-var-requires": "off", 7 | "@typescript-eslint/no-unused-vars": "off", 8 | "@typescript-eslint/camelcase": "off" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/chargebacks/get.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/chargebacks-api/get-chargeback 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const chargeback = await mollieClient.paymentChargebacks.get('chb_n9z0tp', { 11 | paymentId: 'tr_23j4231', 12 | }); 13 | 14 | console.log(chargeback); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/chargebacks/get.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/chargebacks-api/get-chargeback 3 | */ 4 | import createMollieClient, { Chargeback } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const chargeback: Chargeback = await mollieClient.paymentChargebacks.get('chb_n9z0tp', { 11 | paymentId: 'tr_23j4231', 12 | }); 13 | 14 | console.log(chargeback); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/chargebacks/list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/chargebacks-api/list-chargebacks 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const chargebacks = await mollieClient.chargebacks.all(); 11 | 12 | console.log(chargebacks); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/chargebacks/list.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/chargebacks-api/list-chargebacks 3 | */ 4 | import createMollieClient, { List, Chargeback } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const chargebacks: List = await mollieClient.chargebacks.page(); 11 | 12 | console.log(chargebacks); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/customers/create-payment-with-mandate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/create-customer-payment 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payment = await mollieClient.customerPayments.create({ 11 | customerId: 'cst_6ruhPN4V5Q', 12 | amount: { 13 | currency: 'EUR', 14 | value: '10.00', 15 | }, 16 | description: 'Order #12345', 17 | sequenceType: 'first', 18 | redirectUrl: 'https://webshop.example.org/order/12345/', 19 | webhookUrl: 'https://webshop.example.org/payments/webhook/', 20 | }); 21 | 22 | console.log(payment); 23 | } catch (error) { 24 | console.warn(error); 25 | } 26 | })(); 27 | -------------------------------------------------------------------------------- /examples/customers/create-payment-with-mandate.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/create-customer-payment 3 | */ 4 | import createMollieClient, { Payment, SequenceType } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payment: Payment = await mollieClient.customerPayments.create({ 11 | customerId: 'cst_6ruhPN4V5Q', 12 | amount: { 13 | currency: 'EUR', 14 | value: '10.00', 15 | }, 16 | description: 'Order #12345', 17 | sequenceType: SequenceType.first, 18 | redirectUrl: 'https://webshop.example.org/order/12345/', 19 | webhookUrl: 'https://webshop.example.org/payments/webhook/', 20 | }); 21 | 22 | console.log(payment); 23 | } catch (error) { 24 | console.warn(error); 25 | } 26 | })(); 27 | -------------------------------------------------------------------------------- /examples/customers/create-recurring-payment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/create-customer-payment 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const customerId = 'cst_pzhEvnttJ2'; 11 | 12 | const payment = await mollieClient.customerPayments.create({ 13 | amount: { value: '10.00', currency: 'EUR' }, 14 | description: 'Recurring payment', 15 | redirectUrl: 'https://example.org/redirect', 16 | webhookUrl: 'http://example.org/webhook', 17 | metadata: { orderId: 'Order #23' }, 18 | customerId, 19 | sequenceType: 'recurring', 20 | }); 21 | 22 | console.log(payment); 23 | } catch (error) { 24 | console.warn(error); 25 | } 26 | })(); 27 | -------------------------------------------------------------------------------- /examples/customers/create-recurring-payment.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/create-customer-payment 3 | */ 4 | import createMollieClient, { Payment, SequenceType } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const customerId = 'cst_pzhEvnttJ2'; 11 | 12 | const payment: Payment = await mollieClient.customerPayments.create({ 13 | amount: { value: '10.00', currency: 'EUR' }, 14 | description: 'Recurring payment', 15 | redirectUrl: 'https://example.org/redirect', 16 | webhookUrl: 'http://example.org/webhook', 17 | metadata: { orderId: 'Order #23' }, 18 | customerId, 19 | sequenceType: SequenceType.recurring, 20 | }); 21 | 22 | console.log(payment); 23 | } catch (error) { 24 | console.warn(error); 25 | } 26 | })(); 27 | -------------------------------------------------------------------------------- /examples/customers/create.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/create-customer 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const customer = await mollieClient.customers.create({ 11 | name: 'John Doe', 12 | email: 'john.doe@example.org', 13 | }); 14 | 15 | console.log(customer); 16 | } catch (error) { 17 | console.warn(error); 18 | } 19 | })(); 20 | -------------------------------------------------------------------------------- /examples/customers/create.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/create-customer 3 | */ 4 | import createMollieClient, { Customer } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const customer: Customer = await mollieClient.customers.create({ 11 | name: 'John Doe', 12 | email: 'john.doe@example.org', 13 | }); 14 | 15 | console.log(customer); 16 | } catch (error) { 17 | console.warn(error); 18 | } 19 | })(); 20 | -------------------------------------------------------------------------------- /examples/customers/delete.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/delete-customer 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const status = await mollieClient.customers.delete('cst_6ruhPN4V5Q'); 11 | 12 | console.log(status); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/customers/delete.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/delete-customer 3 | */ 4 | import createMollieClient from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const status = await mollieClient.customers.delete('cst_6ruhPN4V5Q'); 11 | 12 | console.log(status); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/customers/get.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/get-customer 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const customer = await mollieClient.customers.get('cst_pzhEvnttJ2'); 11 | 12 | console.log(customer); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/customers/get.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/get-customer 3 | */ 4 | import createMollieClient, { Customer } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const customer: Customer = await mollieClient.customers.get('cst_pzhEvnttJ2'); 11 | 12 | console.log(customer); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/customers/list-payments.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/list-customer-payments 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payments = await mollieClient.customerPayments.all({ customerId: 'cst_pzhEvnttJ2' }); 11 | 12 | console.log(payments); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/customers/list-payments.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/list-customer-payments 3 | */ 4 | import createMollieClient, { List, Payment } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payments: List = await mollieClient.customerPayments.page({ customerId: 'cst_pzhEvnttJ2' }); 11 | 12 | console.log(payments); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/customers/list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/list-customers 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const customers = await mollieClient.customers.all(); 11 | 12 | console.log(customers); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/customers/list.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/list-customers 3 | */ 4 | import createMollieClient, { List, Customer } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const customers: List = await mollieClient.customers.page(); 11 | 12 | console.log(customers); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/customers/update.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/update-customer 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const customer = await mollieClient.customers.update('cst_pzhEvnttJ2', { 11 | name: 'Updated customer name', 12 | email: 'updated-email@example.org', 13 | }); 14 | 15 | console.log(customer); 16 | } catch (error) { 17 | console.warn(error); 18 | } 19 | })(); 20 | -------------------------------------------------------------------------------- /examples/customers/update.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/customers-api/update-customer 3 | */ 4 | import createMollieClient, { Customer } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const customer: Customer = await mollieClient.customers.update('cst_pzhEvnttJ2', { 11 | name: 'Updated customer name', 12 | email: 'updated-email@example.org', 13 | }); 14 | 15 | console.log(customer); 16 | } catch (error) { 17 | console.warn(error); 18 | } 19 | })(); 20 | -------------------------------------------------------------------------------- /examples/mandates/create.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/mandates-api/create-mandate 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const mandate = await mollieClient.customerMandates.create({ 11 | customerId: 'cst_pzhEvnttJ2', 12 | method: 'directdebit', 13 | consumerName: 'John Doe', 14 | consumerAccount: 'NL55INGB0000000000', 15 | consumerBic: 'INGBNL2A', 16 | signatureDate: '2018-05-07', 17 | mandateReference: 'YOUR-COMPANY-MD13804', 18 | }); 19 | 20 | console.log(mandate); 21 | } catch (error) { 22 | console.warn(error); 23 | } 24 | })(); 25 | -------------------------------------------------------------------------------- /examples/mandates/create.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/mandates-api/create-mandate 3 | */ 4 | import createMollieClient, { Mandate, MandateMethod } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const mandate: Mandate = await mollieClient.customerMandates.create({ 11 | customerId: 'cst_pzhEvnttJ2', 12 | method: MandateMethod.directdebit, 13 | consumerName: 'John Doe', 14 | consumerAccount: 'NL55INGB0000000000', 15 | consumerBic: 'INGBNL2A', 16 | signatureDate: '2018-05-07', 17 | mandateReference: 'YOUR-COMPANY-MD13804', 18 | }); 19 | 20 | console.log(mandate); 21 | } catch (error) { 22 | console.warn(error); 23 | } 24 | })(); 25 | -------------------------------------------------------------------------------- /examples/mandates/get.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/mandates-api/get-mandate 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const mandate = await mollieClient.customerMandates.get('mdt_7UmCdnzAfH', { 11 | customerId: 'cst_pzhEvnttJ2', 12 | }); 13 | 14 | console.log(mandate); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/mandates/get.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/mandates-api/get-mandate 3 | */ 4 | import createMollieClient, { Mandate } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const mandate: Mandate = await mollieClient.customerMandates.get('mdt_7UmCdnzAfH', { 11 | customerId: 'cst_pzhEvnttJ2', 12 | }); 13 | 14 | console.log(mandate); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/mandates/list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/mandates-api/list-mandates 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const mandates = await mollieClient.customerMandates.all({ 11 | customerId: 'cst_pzhEvnttJ2', 12 | }); 13 | 14 | console.log(mandates); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/mandates/list.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/mandates-api/list-mandates 3 | */ 4 | import createMollieClient, { List, Mandate } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const mandates: List = await mollieClient.customerMandates.page({ 11 | customerId: 'cst_pzhEvnttJ2', 12 | }); 13 | 14 | console.log(mandates); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/mandates/revoke.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/mandates-api/revoke-mandate 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const status = await mollieClient.customerMandates.revoke('mdt_7UmCdnzAfH', { 11 | customerId: 'cst_pzhEvnttJ2', 12 | }); 13 | 14 | console.log(status); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/mandates/revoke.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/mandates-api/revoke-mandate 3 | */ 4 | import createMollieClient from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const status: boolean = await mollieClient.customerMandates.revoke('mdt_7UmCdnzAfH', { 11 | customerId: 'cst_pzhEvnttJ2', 12 | }); 13 | 14 | console.log(status); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/methods/get-with-issuers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/methods-api/get-method 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const method = await mollieClient.methods.get('ideal', { 11 | include: 'issuers', 12 | }); 13 | 14 | console.log(method); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/methods/get-with-issuers.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/methods-api/get-method 3 | */ 4 | import createMollieClient, { Method, MethodInclude } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const method: Method = await mollieClient.methods.get('ideal', { 11 | include: MethodInclude.issuers, 12 | }); 13 | 14 | console.log(method); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/methods/get.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/methods-api/get-method 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const method = await mollieClient.methods.get('ideal'); 11 | 12 | console.log(method); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/methods/get.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/methods-api/get-method 3 | */ 4 | import createMollieClient, { Method } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const method: Method = await mollieClient.methods.get('ideal'); 11 | 12 | console.log(method); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/methods/list-for-amount-and-currency.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/payments/multicurrency#filtering-payment-methods 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const filteredMethods = await mollieClient.methods.all({ 11 | include: 'issuers', 12 | amount: { 13 | value: '10.00', 14 | currency: 'SEK', 15 | }, 16 | }); 17 | 18 | console.log(filteredMethods); 19 | } catch (error) { 20 | console.warn(error); 21 | } 22 | })(); 23 | -------------------------------------------------------------------------------- /examples/methods/list-for-amount-and-currency.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/payments/multicurrency#filtering-payment-methods 3 | */ 4 | import createMollieClient, { List, Method, MethodInclude } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const filteredMethods: List = await mollieClient.methods.list({ 11 | include: MethodInclude.issuers, 12 | amount: { 13 | value: '10.00', 14 | currency: 'SEK', 15 | }, 16 | }); 17 | 18 | console.log(filteredMethods); 19 | } catch (error) { 20 | console.warn(error); 21 | } 22 | })(); 23 | -------------------------------------------------------------------------------- /examples/methods/list-with-issuers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/methods-api/list-methods 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const methods = await mollieClient.methods.all({ 11 | include: 'issuers', 12 | }); 13 | 14 | console.log(methods); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/methods/list-with-issuers.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/methods-api/list-methods 3 | */ 4 | import createMollieClient, { List, Method, MethodInclude } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const methods: List = await mollieClient.methods.list({ 11 | include: MethodInclude.issuers, 12 | }); 13 | 14 | console.log(methods); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/methods/list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/methods-api/list-methods 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const methods = await mollieClient.methods.all(); 11 | 12 | console.log(methods); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/methods/list.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/methods-api/list-methods 3 | */ 4 | import createMollieClient, { List, Method } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const methods: List = await mollieClient.methods.list(); 11 | 12 | console.log(methods); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/node_modules/@mollie/api-client: -------------------------------------------------------------------------------- 1 | ../../.. -------------------------------------------------------------------------------- /examples/orders/cancel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/orders-api/cancel-order 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const canceledOrder = await mollieClient.orders.cancel('ord_8wmqcHMN4U'); 11 | 12 | console.log(canceledOrder); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/orders/cancel.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/orders-api/cancel-order 3 | */ 4 | import createMollieClient, { Order } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const canceledOrder: Order = await mollieClient.orders.cancel('ord_8wmqcHMN4U'); 11 | 12 | console.log(canceledOrder); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/orders/create_payment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/orders-api/create-order-payment 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payment = await mollieClient.orderPayments.create({ 11 | orderId: 'ord_kEn1PlbGa', 12 | method: PaymentMethod.ideal, 13 | }); 14 | 15 | console.log(payment); 16 | } catch (error) { 17 | console.warn(error); 18 | } 19 | })(); 20 | -------------------------------------------------------------------------------- /examples/orders/create_payment.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/orders-api/create-order-payment 3 | */ 4 | import createMollieClient, { Payment, PaymentMethod } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payment: Payment = await mollieClient.orderPayments.create({ 11 | orderId: 'ord_kEn1PlbGa', 12 | method: PaymentMethod.ideal, 13 | }); 14 | 15 | console.log(payment); 16 | } catch (error) { 17 | console.warn(error); 18 | } 19 | })(); 20 | -------------------------------------------------------------------------------- /examples/orders/get.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/orders-api/get-order 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const order = await mollieClient.orders.get('ord_stTC2WHAuS'); 11 | 12 | console.log(order); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/orders/get.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/orders-api/get-order 3 | */ 4 | import createMollieClient, { Order } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const order: Order = await mollieClient.orders.get('ord_stTC2WHAuS'); 11 | 12 | console.log(order); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/orders/list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/orders-api/list-orders 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const mostRecentOrders = await mollieClient.orders.all(); 11 | const previousOrders = await mostRecentOrders.nextPage(); 12 | 13 | console.log(mostRecentOrders); 14 | console.log(previousOrders); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/orders/list.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/orders-api/list-orders 3 | */ 4 | import createMollieClient, { List, Order } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const mostRecentOrders: List = await mollieClient.orders.page(); 11 | const previousOrders: List = await mostRecentOrders.nextPage(); 12 | 13 | console.log(mostRecentOrders); 14 | console.log(previousOrders); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/orders/update.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/orders-api/update-order 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const order = await mollieClient.orders.update('ord_kEn1PlbGa', { 11 | billingAddress: { 12 | organizationName: 'Mollie B.V.', 13 | streetAndNumber: 'Keizersgracht 313', 14 | city: 'Amsterdam', 15 | region: 'Noord-Holland', 16 | postalCode: '1234AB', 17 | country: 'NL', 18 | title: 'Dhr', 19 | givenName: 'Piet', 20 | familyName: 'Mondriaan', 21 | email: 'piet@mondriaan.com', 22 | phone: '+31208202070', 23 | }, 24 | }); 25 | 26 | console.log(order); 27 | } catch (error) { 28 | console.warn(error); 29 | } 30 | })(); 31 | -------------------------------------------------------------------------------- /examples/orders/update.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/orders-api/update-order 3 | */ 4 | import createMollieClient, { Order } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const order: Order = await mollieClient.orders.update('ord_kEn1PlbGa', { 11 | billingAddress: { 12 | organizationName: 'Mollie B.V.', 13 | streetAndNumber: 'Keizersgracht 313', 14 | city: 'Amsterdam', 15 | region: 'Noord-Holland', 16 | postalCode: '1234AB', 17 | country: 'NL', 18 | title: 'Dhr', 19 | givenName: 'Piet', 20 | familyName: 'Mondriaan', 21 | email: 'piet@mondriaan.com', 22 | phone: '+31208202070', 23 | }, 24 | }); 25 | 26 | console.log(order); 27 | } catch (error) { 28 | console.warn(error); 29 | } 30 | })(); 31 | -------------------------------------------------------------------------------- /examples/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires": true, 3 | "lockfileVersion": 1, 4 | "dependencies": { 5 | "@mollie/api-client": { 6 | "version": "file:..", 7 | "requires": { 8 | "axios": "^0.19.0", 9 | "lodash": "^4.17.15", 10 | "qs": "^6.7.0" 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "dependencies": { 4 | "@mollie/api-client": "../" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/payments/cancel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/payments-api/cancel-payment 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payment = await mollieClient.payments.delete('tr_Eq8xzWUPA4'); 11 | 12 | console.log(payment); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/payments/cancel.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/payments-api/cancel-payment 3 | */ 4 | import createMollieClient, { Payment } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payment: Payment = await mollieClient.payments.delete('tr_Eq8xzWUPA4'); 11 | 12 | console.log(payment); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/payments/create.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/payments-api/create-payment 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payment = await mollieClient.payments.create({ 11 | amount: { 12 | currency: 'EUR', 13 | value: '10.00', // You must send the correct number of decimals, thus we enforce the use of strings 14 | }, 15 | description: 'My first payment', 16 | redirectUrl: 'https://webshop.example.org/order/12345/', 17 | webhookUrl: 'https://webshop.example.org/payments/webhook/', 18 | metadata: { 19 | order_id: '12345', 20 | }, 21 | }); 22 | 23 | console.log(payment); 24 | } catch (error) { 25 | console.warn(error); 26 | } 27 | })(); 28 | -------------------------------------------------------------------------------- /examples/payments/create.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/payments-api/create-payment 3 | */ 4 | import createMollieClient, { Payment } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payment: Payment = await mollieClient.payments.create({ 11 | amount: { 12 | currency: 'EUR', 13 | value: '10.00', // You must send the correct number of decimals, thus we enforce the use of strings 14 | }, 15 | description: 'My first payment', 16 | redirectUrl: 'https://webshop.example.org/order/12345/', 17 | webhookUrl: 'https://webshop.example.org/payments/webhook/', 18 | metadata: { 19 | order_id: '12345', 20 | }, 21 | }); 22 | 23 | console.log(payment); 24 | } catch (error) { 25 | console.warn(error); 26 | } 27 | })(); 28 | -------------------------------------------------------------------------------- /examples/payments/get.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/payments-api/get-payment 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payment = await mollieClient.payments.get('tr_Eq8xzWUPA4'); 11 | 12 | console.log(payment); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/payments/get.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/payments-api/get-payment 3 | */ 4 | import createMollieClient, { Payment } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payment: Payment = await mollieClient.payments.get('tr_Eq8xzWUPA4'); 11 | 12 | console.log(payment); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/payments/release.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/release-authorization 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payment = await mollieClient.payments.releaseAuthorization('tr_Eq8xzWUPA4'); 11 | 12 | console.log(payment); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/payments/release.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/release-authorization 3 | */ 4 | import createMollieClient, { Payment } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payment: Payment = await mollieClient.payments.releaseAuthorization('tr_Eq8xzWUPA4'); 11 | 12 | console.log(payment); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/payments/webhook.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/payments-api/get-payment 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payment = await mollieClient.payments.get('tr_Eq8xzWUPA4'); 11 | 12 | // Check if payment is paid 13 | const isPaid = payment.isPaid(); 14 | 15 | if (isPaid) { 16 | console.log('Payment is paid'); 17 | } else { 18 | console.log(`Payment is not paid, but instead it is: ${payment.status}`); 19 | } 20 | } catch (error) { 21 | console.warn(error); 22 | } 23 | })(); 24 | -------------------------------------------------------------------------------- /examples/payments/webhook.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/payments-api/get-payment 3 | */ 4 | import createMollieClient, { Payment } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payment: Payment = await mollieClient.payments.get('tr_Eq8xzWUPA4'); 11 | 12 | // Check if payment is paid 13 | const isPaid = payment.isPaid(); 14 | 15 | if (isPaid) { 16 | console.log('Payment is paid'); 17 | } else { 18 | console.log(`Payment is not paid, but instead it is: ${payment.status}`); 19 | } 20 | } catch (error) { 21 | console.warn(error); 22 | } 23 | })(); 24 | -------------------------------------------------------------------------------- /examples/refunds/cancel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/refunds-api/cancel-refund 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const status = await mollieClient.paymentRefunds.cancel('re_4qqhO89gsT', { paymentId: 'tr_WDqYK6vllg' }); 11 | 12 | console.log(status); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/refunds/cancel.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/refunds-api/cancel-refund 3 | */ 4 | import createMollieClient from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const status: boolean = await mollieClient.paymentRefunds.cancel('re_4qqhO89gsT', { paymentId: 'tr_WDqYK6vllg' }); 11 | 12 | console.log(status); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/refunds/create.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/refunds-api/create-refund 3 | * @docs https://docs.mollie.com/reference/v2/orders-api/create-order-refund 4 | */ 5 | const { createMollieClient } = require('@mollie/api-client'); 6 | 7 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 8 | 9 | (async () => { 10 | try { 11 | // Create payment refund 12 | const paymentRefund = await mollieClient.paymentRefunds.create({ 13 | paymentId: 'tr_WDqYK6vllg', 14 | amount: { 15 | value: '5.95', 16 | currency: 'EUR', 17 | }, 18 | }); 19 | 20 | console.log(paymentRefund); 21 | 22 | // Create order refund 23 | const orderRefund = await mollieClient.orderRefunds.create({ 24 | orderId: 'ord_stTC2WHAuS', 25 | lines: [ 26 | { 27 | id: 'odl_dgtxyl', 28 | quantity: 1, 29 | }, 30 | ], 31 | description: 'Required quantity not in stock, refunding one photo book.', 32 | }); 33 | 34 | console.log(orderRefund); 35 | } catch (error) { 36 | console.warn(error); 37 | } 38 | })(); 39 | -------------------------------------------------------------------------------- /examples/refunds/create.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/refunds-api/create-refund 3 | * @docs https://docs.mollie.com/reference/v2/orders-api/create-order-refund 4 | */ 5 | import createMollieClient, { Refund } from '@mollie/api-client'; 6 | 7 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 8 | 9 | (async () => { 10 | try { 11 | // Create payment refund 12 | const paymentRefund: Refund = await mollieClient.paymentRefunds.create({ 13 | paymentId: 'tr_WDqYK6vllg', 14 | amount: { 15 | value: '5.95', 16 | currency: 'EUR', 17 | }, 18 | }); 19 | 20 | console.log(paymentRefund); 21 | 22 | // Create order refund 23 | const orderRefund: Refund = await mollieClient.orderRefunds.create({ 24 | orderId: 'ord_stTC2WHAuS', 25 | lines: [ 26 | { 27 | id: 'odl_dgtxyl', 28 | quantity: 1, 29 | }, 30 | ], 31 | description: 'Required quantity not in stock, refunding one photo book.', 32 | }); 33 | 34 | console.log(orderRefund); 35 | } catch (error) { 36 | console.warn(error); 37 | } 38 | })(); 39 | -------------------------------------------------------------------------------- /examples/refunds/get.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/refunds-api/get-refund 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const refund = await mollieClient.paymentRefunds.get('re_4qqhO89gsT', { paymentId: 'tr_WDqYK6vllg' }); 11 | 12 | console.log(refund); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/refunds/get.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/refunds-api/get-refund 3 | */ 4 | import createMollieClient, { Refund } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const refund: Refund = await mollieClient.paymentRefunds.get('re_4qqhO89gsT', { paymentId: 'tr_WDqYK6vllg' }); 11 | 12 | console.log(refund); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/refunds/list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/refunds-api/list-refunds 3 | * @docs https://docs.mollie.com/reference/v2/orders-api/list-order-refunds 4 | */ 5 | const { createMollieClient } = require('@mollie/api-client'); 6 | 7 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 8 | 9 | (async () => { 10 | try { 11 | // Payment refunds 12 | const paymentRefunds = await mollieClient.paymentRefunds.all({ paymentId: 'tr_WDqYK6vllg' }); 13 | 14 | console.log(paymentRefunds); 15 | 16 | // Order refunds 17 | const orderRefunds = await mollieClient.orderRefunds.all({ orderId: 'ord_stTC2WHAuS' }); 18 | 19 | console.log(orderRefunds); 20 | } catch (error) { 21 | console.warn(error); 22 | } 23 | })(); 24 | -------------------------------------------------------------------------------- /examples/refunds/list.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/refunds-api/list-refunds 3 | * @docs https://docs.mollie.com/reference/v2/orders-api/list-order-refunds 4 | */ 5 | import createMollieClient, { List, Refund } from '@mollie/api-client'; 6 | 7 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 8 | 9 | (async () => { 10 | try { 11 | // Payment refunds 12 | const paymentRefunds: List = await mollieClient.paymentRefunds.page({ paymentId: 'tr_WDqYK6vllg' }); 13 | 14 | console.log(paymentRefunds); 15 | 16 | // Order refunds 17 | const orderRefunds: List = await mollieClient.orderRefunds.page({ orderId: 'ord_stTC2WHAuS' }); 18 | 19 | console.log(orderRefunds); 20 | } catch (error) { 21 | console.warn(error); 22 | } 23 | })(); 24 | -------------------------------------------------------------------------------- /examples/subscriptions/cancel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/subscriptions-api/cancel-subscription 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const subscription = await mollieClient.customerSubscriptions.delete('sub_PCN3U3U27K', { 11 | customerId: 'cst_pzhEvnttJ2', 12 | }); 13 | 14 | console.log(subscription); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/subscriptions/cancel.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/subscriptions-api/cancel-subscription 3 | */ 4 | import createMollieClient, { Subscription } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const subscription: Subscription = await mollieClient.customerSubscriptions.delete('sub_PCN3U3U27K', { 11 | customerId: 'cst_pzhEvnttJ2', 12 | }); 13 | 14 | console.log(subscription); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/subscriptions/create.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/subscriptions-api/create-subscription 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const subscription = await mollieClient.customerSubscriptions.create({ 11 | customerId: 'cst_pzhEvnttJ2', 12 | amount: { value: '24.00', currency: 'EUR' }, 13 | times: 4, 14 | interval: '3 months', 15 | description: 'Quarterly payment', 16 | webhookUrl: 'https://webshop.example.org/payments/webhook/', 17 | }); 18 | 19 | console.log(subscription); 20 | } catch (error) { 21 | console.warn(error); 22 | } 23 | })(); 24 | -------------------------------------------------------------------------------- /examples/subscriptions/create.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/subscriptions-api/create-subscription 3 | */ 4 | import createMollieClient, { Subscription } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const subscription: Subscription = await mollieClient.customerSubscriptions.create({ 11 | customerId: 'cst_pzhEvnttJ2', 12 | amount: { value: '24.00', currency: 'EUR' }, 13 | times: 4, 14 | interval: '3 months', 15 | description: 'Quarterly payment', 16 | webhookUrl: 'https://webshop.example.org/payments/webhook/', 17 | }); 18 | 19 | console.log(subscription); 20 | } catch (error) { 21 | console.warn(error); 22 | } 23 | })(); 24 | -------------------------------------------------------------------------------- /examples/subscriptions/get.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/subscriptions-api/get-subscription 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const subscription = await mollieClient.customerSubscriptions.get('sub_PCN3U3U27K', { 11 | customerId: 'cst_pzhEvnttJ2', 12 | }); 13 | 14 | console.log(subscription); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/subscriptions/get.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/subscriptions-api/get-subscription 3 | */ 4 | import createMollieClient, { Subscription } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const subscription: Subscription = await mollieClient.customerSubscriptions.get('sub_PCN3U3U27K', { 11 | customerId: 'cst_pzhEvnttJ2', 12 | }); 13 | 14 | console.log(subscription); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/subscriptions/list-payments.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/subscriptions-api/list-subscriptions-payments 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payments = await mollieClient.subscriptionPayments.list({ customerId: 'cst_8wmqcHMN4U', subscriptionId: 'sub_8JfGzs6v3K' }); 11 | 12 | console.log(payments); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/subscriptions/list-payments.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/subscriptions-api/list-subscriptions-payments 3 | */ 4 | import createMollieClient, { List, Payment } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const payments: List = await mollieClient.subscriptionPayments.page({ customerId: 'cst_8wmqcHMN4U', subscriptionId: 'sub_8JfGzs6v3K' }); 11 | 12 | console.log(payments); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/subscriptions/list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/subscriptions-api/list-subscriptions 3 | */ 4 | const { createMollieClient } = require('@mollie/api-client'); 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const subscriptions = await mollieClient.customerSubscriptions.all({ 11 | customerId: 'cst_pzhEvnttJ2', 12 | }); 13 | 14 | console.log(subscriptions); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/subscriptions/list.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/subscriptions-api/list-subscriptions 3 | */ 4 | import createMollieClient, { List, Subscription } from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const subscriptions: List = await mollieClient.customerSubscriptions.page({ 11 | customerId: 'cst_pzhEvnttJ2', 12 | }); 13 | 14 | console.log(subscriptions); 15 | } catch (error) { 16 | console.warn(error); 17 | } 18 | })(); 19 | -------------------------------------------------------------------------------- /examples/terminals/get.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/terminals-api/get-terminal 3 | */ 4 | import createMollieClient from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const terminal = await mollieClient.terminals.get('term_7MgL4wea46qkRcoTZjWEH'); 11 | 12 | console.log(terminal); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/terminals/list.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @docs https://docs.mollie.com/reference/v2/terminals-api/list-terminals 3 | */ 4 | import createMollieClient from '@mollie/api-client'; 5 | 6 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 7 | 8 | (async () => { 9 | try { 10 | const terminals = await mollieClient.terminals.page({}); 11 | 12 | console.log(terminals); 13 | } catch (error) { 14 | console.warn(error); 15 | } 16 | })(); 17 | -------------------------------------------------------------------------------- /examples/with-express/01-new-payment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Example 01 - How to prepare a new payment with the Mollie API. 3 | */ 4 | 5 | const express = require('express'); 6 | const { createMollieClient } = require('@mollie/api-client'); 7 | 8 | const app = express(); 9 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 10 | 11 | app.get('/', (req, res) => { 12 | const orderId = new Date().getTime(); 13 | 14 | mollieClient.payments 15 | .create({ 16 | amount: { value: '10.00', currency: 'EUR' }, 17 | description: 'New payment', 18 | redirectUrl: `https://example.org/redirect?orderId=${orderId}`, 19 | webhookUrl: `http://example.org/webhook?orderId=${orderId}`, 20 | metadata: { orderId }, 21 | }) 22 | .then(payment => { 23 | // Redirect the consumer to complete the payment using `payment.getPaymentUrl()`. 24 | res.redirect(payment.getPaymentUrl()); 25 | }) 26 | .catch(error => { 27 | // Do some proper error handling. 28 | res.send(error); 29 | }); 30 | }); 31 | 32 | app.listen(8000, () => console.log('Example app listening on port 8000.')); 33 | -------------------------------------------------------------------------------- /examples/with-express/02-webhook-verification.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Example 02 - How to verify Mollie API payments with a webhook. 3 | * 4 | * @see https://www.mollie.com/en/docs/webhook 5 | */ 6 | 7 | const express = require('express'); 8 | const { createMollieClient } = require('@mollie/api-client'); 9 | 10 | const app = express(); 11 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 12 | 13 | /** 14 | * Your webhook will be called with a single POST-parameter named id, which for example will 15 | * contain the value tr_7r4n54c710n. You should use that id to actively fetch the payment to 16 | * find out about its status. 17 | */ 18 | app.post('/webhook', (req, res) => { 19 | mollieClient.payments 20 | .get(req.body.id) 21 | .then(payment => { 22 | if (payment.isPaid()) { 23 | // Hooray, you've received a payment! You can start shipping to the consumer. 24 | } else if (!payment.isOpen()) { 25 | // The payment isn't paid and has expired. We can assume it was aborted. 26 | } 27 | res.send(payment.status); 28 | }) 29 | .catch(error => { 30 | // Do some proper error handling. 31 | res.send(error); 32 | }); 33 | }); 34 | 35 | app.listen(8000, () => console.log('Example app listening on port 8000.')); 36 | -------------------------------------------------------------------------------- /examples/with-express/03-return-page.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Example 03 - How to show a return page to the customer. 3 | */ 4 | 5 | const express = require('express'); 6 | const { createMollieClient } = require('@mollie/api-client'); 7 | 8 | const app = express(); 9 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 10 | 11 | // Fetch the order from your database. 12 | const getOrder = orderId => ({ 13 | orderId, 14 | paymentId: 'tr_7r4n54c710n', 15 | }); 16 | 17 | app.get('/return-page', (req, res) => { 18 | // If you included an order ID in the redirectUrl you can use it to get the payment ID. 19 | const order = getOrder(req.query.orderId); 20 | 21 | mollieClient.payments 22 | .get(order.paymentId) 23 | .then(payment => { 24 | // Show the consumer the status of the payment using `payment.status`. 25 | res.send(payment.status); 26 | }) 27 | .catch(error => { 28 | // Do some proper error handling. 29 | res.send(error); 30 | }); 31 | }); 32 | 33 | app.listen(8000, () => console.log('Example app listening on port 8000.')); 34 | -------------------------------------------------------------------------------- /examples/with-express/04-ideal-payment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Example 04 - How to prepare an iDEAL payment with the Mollie API. 3 | */ 4 | 5 | const express = require('express'); 6 | const { createMollieClient } = require('@mollie/api-client'); 7 | 8 | const app = express(); 9 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 10 | 11 | app.get('/', (req, res) => { 12 | const selectedIssuer = req.query.issuer; 13 | 14 | // Show a payment screen where the consumer can choose its issuing bank. 15 | if (!selectedIssuer) { 16 | mollieClient.methods 17 | .all({ include: 'issuers' }) 18 | .then(methods => methods.filter(({ id }) => id === 'ideal')) 19 | .then(methods => { 20 | res.send(`
21 | ${methods.map( 22 | method => ` 23 |

Select ${method.description} issuer

24 | 25 | `, 26 | )} 27 | 28 |
`); 29 | }) 30 | .catch(error => { 31 | // Do some proper error handling. 32 | res.send(error); 33 | }); 34 | 35 | return; 36 | } 37 | 38 | const orderId = new Date().getTime(); 39 | 40 | // After which you can create an iDEAL payment with the selected issuer. 41 | mollieClient.payments 42 | .create({ 43 | amount: { value: '10.00', currency: 'EUR' }, 44 | description: 'Test payment', 45 | redirectUrl: `https://example.org/redirect?orderId=${orderId}`, 46 | webhookUrl: `http://example.org/webhook?orderId=${orderId}`, 47 | metadata: { orderId }, 48 | method: 'ideal', 49 | issuer: selectedIssuer, 50 | }) 51 | .then(payment => { 52 | // Redirect the consumer to complete the payment using `payment.getPaymentUrl()`. 53 | res.redirect(payment.getPaymentUrl()); 54 | }) 55 | .catch(error => { 56 | // Do some proper error handling. 57 | res.send(error); 58 | }); 59 | }); 60 | 61 | app.listen(8000, () => console.log('Example app listening on port 8000.')); 62 | -------------------------------------------------------------------------------- /examples/with-express/05-payments-history.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Example 05 - How to retrieve your payments history. 3 | */ 4 | 5 | const express = require('express'); 6 | const { createMollieClient } = require('@mollie/api-client'); 7 | 8 | const app = express(); 9 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 10 | 11 | app.get('/', (req, res) => { 12 | let paymentParameters = { 13 | limit: 5, 14 | }; 15 | 16 | if (req.query.from) { 17 | paymentParameters = { 18 | ...paymentParameters, 19 | from: req.query.from, 20 | }; 21 | } 22 | 23 | mollieClient.payments 24 | .all(paymentParameters) 25 | .then(payments => { 26 | res.send(` 27 |
    28 | ${payments 29 | .map( 30 | payment => `
  • 31 | Payment ID: ${payment.id}
    32 | Method: ${payment.method}
    33 | Amount: ${payment.amount.value} ${payment.amount.currency}
    34 | Created at: ${new Date(payment.createdAt)} 35 |
  • `, 36 | ) 37 | .join('')} 38 |
39 | ${payments.previousPageCursor ? `Previous | ` : ''} 40 | ${payments.nextPageCursor ? `Next` : ''} 41 | `); 42 | }) 43 | .catch(error => { 44 | // Do some proper error handling. 45 | res.send(error); 46 | }); 47 | }); 48 | 49 | app.listen(8000, () => console.log('Example app listening on port 8000.')); 50 | -------------------------------------------------------------------------------- /examples/with-express/06-refund-payment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Example 06 - How to refund a Payment. 3 | * 4 | * @see https://www.mollie.com/en/docs/reference/refunds/create 5 | */ 6 | 7 | const { createMollieClient } = require('@mollie/api-client'); 8 | 9 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 10 | 11 | mollieClient.paymentRefunds 12 | .create({ 13 | paymentId: 'tr_Vw3BTrxd9C', 14 | amount: { 15 | value: '5.00', 16 | currency: 'EUR', 17 | }, 18 | }) 19 | .then(refund => { 20 | // New refund (#`refund.id`) created with amount: `refund.amount`. 21 | }) 22 | .catch(error => { 23 | // Do some proper error handling. 24 | }); 25 | -------------------------------------------------------------------------------- /examples/with-express/07-new-customer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Example 07 - How to create a new customer. 3 | */ 4 | 5 | const { createMollieClient } = require('@mollie/api-client'); 6 | 7 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 8 | 9 | mollieClient.customers 10 | .create({ 11 | name: 'Luke Skywalker', 12 | email: 'luke@example.org', 13 | metadata: { 14 | isJedi: true, 15 | }, 16 | }) 17 | .then(customer => { 18 | // New customer created with ID `customer.id` and name `customer.name`. 19 | }) 20 | .catch(error => { 21 | // Do some proper error handling. 22 | }); 23 | -------------------------------------------------------------------------------- /examples/with-express/08-new-customer-payment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Example 08 - How to create a new customer payment. 3 | * 4 | * @see https://www.mollie.com/en/docs/reference/customers/create-payment 5 | */ 6 | 7 | const { createMollieClient } = require('@mollie/api-client'); 8 | 9 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 10 | 11 | mollieClient.customers 12 | .all() 13 | .then(customers => { 14 | const customerId = customers[0].id; // Select one of your customers. 15 | const orderId = new Date().getTime(); 16 | 17 | mollieClient.customerPayments 18 | .create({ 19 | amount: { value: '10.00', currency: 'EUR' }, 20 | description: `Customer payment for ${customerId}`, 21 | redirectUrl: `https://example.org/redirect?orderId=${orderId}`, 22 | webhookUrl: `http://example.org/webhook?orderId=${orderId}`, 23 | metadata: { orderId }, 24 | customerId, 25 | }) 26 | .then(payment => { 27 | // Redirect customer to payment screen with `payment.getPaymentUrl()`. 28 | }) 29 | .catch(error => { 30 | // Do some proper error handling. 31 | }); 32 | }) 33 | .catch(error => { 34 | // Do some proper error handling. 35 | }); 36 | -------------------------------------------------------------------------------- /examples/with-express/09-customer-payments-history.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Example 09 - How to list all a customer's payments. 3 | */ 4 | 5 | const { createMollieClient } = require('@mollie/api-client'); 6 | 7 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 8 | 9 | mollieClient.customerPayments 10 | .all({ 11 | count: 50, 12 | customerId: 'cst_cu5t0m3r', 13 | }) 14 | .then(payments => { 15 | // List the customer's payments. 16 | }) 17 | .catch(error => { 18 | // Do some proper error handling. 19 | }); 20 | -------------------------------------------------------------------------------- /examples/with-express/10-recurring-first-payment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Example 10 - How to create a first payment to allow for recurring payments later. 3 | */ 4 | 5 | const { createMollieClient } = require('@mollie/api-client'); 6 | 7 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 8 | 9 | const orderId = new Date().getTime(); 10 | 11 | mollieClient.customerPayments 12 | .create({ 13 | amount: { value: '0.01', currency: 'EUR' }, 14 | description: 'A first payment for recurring', 15 | redirectUrl: `https://example.org/redirect?orderId=${orderId}`, 16 | webhookUrl: `http://example.org/webhook?orderId=${orderId}`, 17 | sequenceType: 'first', 18 | customerId: 'cst_2mVdVmuVq2', 19 | }) 20 | .then(payment => { 21 | // Redirect the customer to complete the payment using `payment.getPaymentUrl()`. 22 | }) 23 | .catch(error => { 24 | // Do some proper error handling. 25 | }); 26 | -------------------------------------------------------------------------------- /examples/with-express/11-recurring-payment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Example 11 - How to create an on-demand recurring payment. 3 | */ 4 | 5 | const { createMollieClient } = require('@mollie/api-client'); 6 | 7 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 8 | 9 | mollieClient.customers 10 | .all() 11 | .then(customers => { 12 | const customerId = customers[0].id; // Select one of your customers. 13 | const orderId = new Date().getTime(); 14 | 15 | mollieClient.customerPayments 16 | .create({ 17 | amount: { value: '10.00', currency: 'EUR' }, 18 | description: `Recurring payment for customer ${customerId}`, 19 | redirectUrl: `https://example.org/redirect?orderId=${orderId}`, 20 | webhookUrl: `http://example.org/webhook?orderId=${orderId}`, 21 | metadata: { orderId }, 22 | customerId, 23 | sequenceType: 'recurring', 24 | }) 25 | .then(payment => { 26 | // Redirect customer to payment screen with `payment.getPaymentUrl()`. 27 | }) 28 | .catch(error => { 29 | // Do some proper error handling. 30 | }); 31 | }) 32 | .catch(error => { 33 | // Do some proper error handling. 34 | }); 35 | -------------------------------------------------------------------------------- /examples/with-express/16-recurring-subscription.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Example 16 - How to prepare a subscription with the Mollie API. 3 | */ 4 | 5 | const { createMollieClient } = require('@mollie/api-client'); 6 | 7 | const mollieClient = createMollieClient({ apiKey: 'test_dHar4XY7LxsDOtmnkVtjNVWXLSlXsM' }); 8 | 9 | mollieClient.customers.all().then(customers => { 10 | mollieClient.customerSubscriptions 11 | .create({ 12 | customerId: customers[0].id, 13 | amount: { value: '24.00', currency: 'EUR' }, 14 | times: 4, 15 | interval: '3 months', 16 | description: 'Quarterly payment', 17 | webhookUrl: 'https://webshop.example.org/payments/webhook/', 18 | }) 19 | .then(({ id }) => { 20 | // i.e. send confirmation email 21 | }) 22 | .catch(error => { 23 | // Do some proper error handling 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: 'node', 3 | setupFilesAfterEnv: ['jest-bluster'], 4 | testRegex: '/tests/.*/.+\\.test\\.[jt]s$', 5 | transform: { 6 | '\\.[jt]s$': 'babel-jest' 7 | } 8 | }; -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | const { join } = require('path'); 2 | const json = require('rollup-plugin-json'); 3 | const resolve = require('rollup-plugin-node-resolve'); 4 | const babel = require('rollup-plugin-babel'); 5 | 6 | module.exports = { 7 | input: join('src', 'createMollieClient.ts'), 8 | external: [ 9 | // These Node.js internals are external to our bundles… 10 | 'crypto', 'https', 'querystring', 'url', 'util', 11 | // …as are the dependencies listed in our package.json. 12 | ...Object.keys(require('./package.json').dependencies), 13 | ], 14 | output: [{ file: join('dist', 'mollie.cjs.js'), format: 'cjs' }, { file: join('dist', 'mollie.esm.js'), format: 'es' }], 15 | plugins: [ 16 | json(), 17 | resolve({ 18 | extensions: ['.ts'], 19 | customResolveOptions: { 20 | moduleDirectory: 'src', 21 | }, 22 | preferBuiltins: true, 23 | }), 24 | babel({ 25 | extensions: ['.ts'], 26 | }), 27 | { 28 | name: 'cert', 29 | transform(code, id) { 30 | if (id.endsWith('.pem') == false) { 31 | return null; 32 | } 33 | return { 34 | code: `export default ${JSON.stringify(code)}`, 35 | map: { mappings: '' } 36 | }; 37 | } 38 | } 39 | ], 40 | }; 41 | -------------------------------------------------------------------------------- /src/Options.ts: -------------------------------------------------------------------------------- 1 | import type MaybeArray from './types/MaybeArray'; 2 | import type Xor from './types/Xor'; 3 | 4 | type Options = Xor< 5 | { 6 | /** 7 | * The Mollie API key, starting with `'test_'` or `'live_'`. 8 | */ 9 | apiKey: string; 10 | }, 11 | { 12 | /** 13 | * OAuth access token, starting with `'access_''. 14 | */ 15 | accessToken: string; 16 | } 17 | > & { 18 | /** 19 | * One or an array of version strings of the software you are using, such as `'RockenbergCommerce/3.1.12'`. 20 | */ 21 | versionStrings?: MaybeArray; 22 | /** 23 | * The headers set in the requests sent to the Mollie API. `Authorization`, `User-Agent`, `Accept`, 24 | * `Accept-Encoding`, and `Content-Type` are set by this library directly. Setting them here has no effect. 25 | */ 26 | headers?: Record; 27 | /** 28 | * The URL of the root of the Mollie API. Default: `'https://api.mollie.com:443/v2/'`. 29 | */ 30 | apiEndpoint?: string; 31 | }; 32 | 33 | const falsyDescriptions = new Map([ 34 | [undefined, 'undefined'], 35 | [null, 'null'], 36 | ['', 'an empty string'], 37 | ]); 38 | 39 | /** 40 | * Returns an error message (string) similar to `"Parameter "×" is null."` if a property with the passed key exists in 41 | * the passed options object, or `null` if said property does not exist. 42 | */ 43 | function describeFalsyOption(options: Options, key: keyof Options) { 44 | if (key in options == false) { 45 | return null; 46 | } 47 | return `Parameter "${key}" is ${falsyDescriptions.get(options[key]) ?? options[key]}.`; 48 | } 49 | 50 | /** 51 | * Throws a `TypeError` if the passed options object does not contain an `apiKey` or an `accessToken`. 52 | */ 53 | export function checkCredentials(options: Options) { 54 | if (!options.apiKey && !options.accessToken) { 55 | throw new TypeError(describeFalsyOption(options, 'apiKey') ?? describeFalsyOption(options, 'accessToken') ?? 'Missing parameter "apiKey" or "accessToken".'); 56 | } 57 | } 58 | 59 | export default Options; 60 | -------------------------------------------------------------------------------- /src/binders/Binder.ts: -------------------------------------------------------------------------------- 1 | import breakUrl from '../communication/breakUrl'; 2 | import type Page from '../data/page/Page'; 3 | import type Maybe from '../types/Maybe'; 4 | 5 | /** 6 | * A binder is the interface for a certain type of information. There is a binder for orders, and one for customers, et 7 | * cetera. 8 | */ 9 | export default class Binder> { 10 | /** 11 | * Injects `nextPage`, `nextPageCursor`, `previousPage`, and `previousPageCursor` into the passed list. 12 | */ 13 | protected injectPaginationHelpers

(input: Array & Pick, 'links'>, list: (parameters: P) => Promise>, selfParameters: P = {} as P): Page { 14 | const { links } = input; 15 | let nextPage: Maybe<() => Promise>>; 16 | let nextPageCursor: Maybe; 17 | if (links.next != null) { 18 | const [, query] = breakUrl(links.next.href); 19 | nextPage = list.bind(this, { 20 | ...selfParameters, 21 | ...query, 22 | }); 23 | nextPageCursor = query.from; 24 | } 25 | let previousPage: Maybe<() => Promise>>; 26 | let previousPageCursor: Maybe; 27 | if (links.previous != null) { 28 | const [, query] = breakUrl(links.previous.href); 29 | previousPage = list.bind(this, { 30 | ...selfParameters, 31 | ...query, 32 | }); 33 | previousPageCursor = query.from; 34 | } 35 | return Object.assign(input, { 36 | nextPage, 37 | nextPageCursor, 38 | previousPage, 39 | previousPageCursor, 40 | }) as Page; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/binders/applePay/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type IdempotencyParameter } from '../../types/parameters'; 2 | 3 | export interface RequestPaymentSessionParameters extends IdempotencyParameter { 4 | /** 5 | * The `validationUrl` you got from the [ApplePayValidateMerchant event](https://developer.apple.com/documentation/apple_pay_on_the_web/applepayvalidatemerchantevent). 6 | * 7 | * A [list of all valid host names](https://developer.apple.com/documentation/apple_pay_on_the_web/setting_up_your_server#3172427) for merchant validation is available. You should white list these 8 | * in your application and reject any `validationUrl` that have a host name not in the list. 9 | * 10 | * @see https://docs.mollie.com/reference/v2/wallets-api/request-apple-pay-payment-session?path=validationUrl#parameters 11 | */ 12 | validationUrl: string; 13 | /** 14 | * The domain of your web shop, that is visible in the browser's location bar. For example `pay.myshop.com`. 15 | * 16 | * @see https://docs.mollie.com/reference/v2/wallets-api/request-apple-pay-payment-session?path=domain#parameters 17 | */ 18 | domain: string; 19 | } 20 | -------------------------------------------------------------------------------- /src/binders/chargebacks/ChargebacksBinder.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Chargeback from '../../data/chargebacks/Chargeback'; 3 | import { type ChargebackData } from '../../data/chargebacks/Chargeback'; 4 | import type Page from '../../data/page/Page'; 5 | import alias from '../../plumbing/alias'; 6 | import renege from '../../plumbing/renege'; 7 | import type Callback from '../../types/Callback'; 8 | import Binder from '../Binder'; 9 | import { type IterateParameters, type PageParameters } from './parameters'; 10 | 11 | const pathSegment = 'chargebacks'; 12 | 13 | export default class ChargebacksBinder extends Binder { 14 | constructor(protected readonly networkClient: TransformingNetworkClient) { 15 | super(); 16 | alias(this, { page: ['all', 'list'] }); 17 | } 18 | 19 | /** 20 | * Retrieve all chargebacks filed for your payments. 21 | * 22 | * The results are paginated. See pagination for more information. 23 | * 24 | * @since 3.0.0 25 | * @see https://docs.mollie.com/reference/v2/chargebacks-api/list-chargebacks 26 | */ 27 | public page(parameters?: PageParameters): Promise>; 28 | public page(parameters: PageParameters, callback: Callback>): void; 29 | public page(parameters: PageParameters = {}) { 30 | if (renege(this, this.page, ...arguments)) return; 31 | return this.networkClient.page(pathSegment, 'chargebacks', parameters).then(result => this.injectPaginationHelpers(result, this.page, parameters)); 32 | } 33 | 34 | /** 35 | * Retrieve all chargebacks filed for your payments. 36 | * 37 | * The results are paginated. See pagination for more information. 38 | * 39 | * @since 3.6.0 40 | * @see https://docs.mollie.com/reference/v2/chargebacks-api/list-chargebacks 41 | */ 42 | public iterate(parameters?: IterateParameters) { 43 | const { valuesPerMinute, ...query } = parameters ?? {}; 44 | return this.networkClient.iterate(pathSegment, 'chargebacks', query, valuesPerMinute); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/binders/chargebacks/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type ChargebackEmbed } from '../../data/chargebacks/Chargeback'; 2 | import { type PaginationParameters, type ThrottlingParameter } from '../../types/parameters'; 3 | 4 | export type PageParameters = PaginationParameters & { 5 | profileId?: string; 6 | embed?: ChargebackEmbed[]; 7 | }; 8 | 9 | export type IterateParameters = Omit & ThrottlingParameter; 10 | -------------------------------------------------------------------------------- /src/binders/customers/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type CustomerData } from '../../data/customers/Customer'; 2 | import { type IdempotencyParameter, type PaginationParameters, type ThrottlingParameter } from '../../types/parameters'; 3 | import type PickOptional from '../../types/PickOptional'; 4 | 5 | interface ContextParameter { 6 | testmode?: boolean; 7 | } 8 | 9 | export type CreateParameters = ContextParameter & PickOptional & IdempotencyParameter; 10 | 11 | export type GetParameters = ContextParameter; 12 | 13 | export type PageParameters = ContextParameter & PaginationParameters; 14 | 15 | export type IterateParameters = Omit & ThrottlingParameter; 16 | 17 | export type UpdateParameters = ContextParameter & PickOptional; 18 | 19 | export type DeleteParameters = ContextParameter & IdempotencyParameter; 20 | -------------------------------------------------------------------------------- /src/binders/customers/payments/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type PaymentMethod } from '../../../data/global'; 2 | import { type PaymentData } from '../../../data/payments/data'; 3 | import type MaybeArray from '../../../types/MaybeArray'; 4 | import { type IdempotencyParameter, type PaginationParameters, type ThrottlingParameter } from '../../../types/parameters'; 5 | import type PickOptional from '../../../types/PickOptional'; 6 | 7 | interface ContextParameters { 8 | customerId: string; 9 | } 10 | 11 | export type CreateParameters = ContextParameters & 12 | Pick & 13 | PickOptional & { 14 | /** 15 | * Normally, a payment method screen is shown. However, when using this parameter, you can choose a specific payment method and your customer will skip the selection screen and is sent directly to 16 | * the chosen payment method. The parameter enables you to fully integrate the payment method selection into your website. 17 | * 18 | * You can also specify the methods in an array. By doing so we will still show the payment method selection screen but will only show the methods specified in the array. For example, you can use 19 | * this functionality to only show payment methods from a specific country to your customer `['bancontact', 'belfius']`. 20 | * 21 | * Possible values: `applepay` `bancontact` `banktransfer` `belfius` `creditcard` `directdebit` `eps` `giftcard` `giropay` `ideal` `kbc` `mybank` `paypal` `paysafecard` `przelewy24` `sofort` 22 | * 23 | * @see https://docs.mollie.com/reference/v2/payments-api/create-payment?path=method#parameters 24 | */ 25 | method?: MaybeArray; 26 | } & IdempotencyParameter; 27 | 28 | export type PageParameters = ContextParameters & PaginationParameters; 29 | 30 | export type IterateParameters = Omit & ThrottlingParameter; 31 | -------------------------------------------------------------------------------- /src/binders/customers/subscriptions/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type SubscriptionData } from '../../../data/subscriptions/data'; 2 | import { type IdempotencyParameter, type PaginationParameters, type ThrottlingParameter } from '../../../types/parameters'; 3 | import type PickOptional from '../../../types/PickOptional'; 4 | 5 | interface ContextParameters { 6 | customerId: string; 7 | testmode?: boolean; 8 | } 9 | 10 | export type CreateParameters = ContextParameters & 11 | Pick & 12 | PickOptional & 13 | IdempotencyParameter; 14 | 15 | export type GetParameters = ContextParameters; 16 | 17 | export type PageParameters = ContextParameters & PaginationParameters; 18 | 19 | export type IterateParameters = Omit & ThrottlingParameter; 20 | 21 | export type UpdateParameters = ContextParameters & 22 | Pick & 23 | PickOptional; 24 | 25 | export type CancelParameters = ContextParameters & IdempotencyParameter; 26 | -------------------------------------------------------------------------------- /src/binders/onboarding/OnboardingBinder.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import { type OnboardingData } from '../../data/onboarding/data'; 3 | import type Onboarding from '../../data/onboarding/Onboarding'; 4 | import renege from '../../plumbing/renege'; 5 | import type Callback from '../../types/Callback'; 6 | import Binder from '../Binder'; 7 | import { type SubmitParameters } from './parameters'; 8 | 9 | const pathSegments = 'onboarding/me'; 10 | 11 | export default class OnboardingBinder extends Binder { 12 | constructor(protected readonly networkClient: TransformingNetworkClient) { 13 | super(); 14 | } 15 | 16 | /** 17 | * Get the status of onboarding of the authenticated organization. 18 | * 19 | * @since 3.2.0 20 | * @see https://docs.mollie.com/reference/v2/onboarding-api/get-onboarding-status 21 | */ 22 | public get(): Promise; 23 | public get(callback: Callback): void; 24 | public get() { 25 | if (renege(this, this.get, ...arguments)) return; 26 | return this.networkClient.get(pathSegments); 27 | } 28 | 29 | /** 30 | * Submit data that will be prefilled in the merchant's onboarding. The data you submit will only be processed when the onboarding status is `needs-data`. 31 | * 32 | * @since 3.2.0 33 | * @see https://docs.mollie.com/reference/v2/onboarding-api/submit-onboarding-data 34 | */ 35 | public submit(parameters?: SubmitParameters): Promise; 36 | public submit(parameters: SubmitParameters, callback: Callback): void; 37 | public submit(parameters: SubmitParameters = {}) { 38 | if (renege(this, this.submit, ...arguments)) return; 39 | return this.networkClient.post(pathSegments, parameters); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/binders/organizations/OrganizationsBinder.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Organization from '../../data/organizations/Organizations'; 3 | import { type OrganizationData } from '../../data/organizations/Organizations'; 4 | import assertWellFormedId from '../../plumbing/assertWellFormedId'; 5 | import renege from '../../plumbing/renege'; 6 | import type Callback from '../../types/Callback'; 7 | import Binder from '../Binder'; 8 | 9 | const pathSegment = 'organizations'; 10 | 11 | export default class OrganizationsBinder extends Binder { 12 | constructor(protected readonly networkClient: TransformingNetworkClient) { 13 | super(); 14 | } 15 | 16 | /** 17 | * Retrieve an organization by its ID. 18 | * 19 | * @since 3.2.0 20 | * @see https://docs.mollie.com/reference/v2/organizations-api/get-organization 21 | */ 22 | public get(id: string): Promise; 23 | public get(id: string, callback: Callback): void; 24 | public get(id: string) { 25 | if (renege(this, this.get, ...arguments)) return; 26 | assertWellFormedId(id, 'organization'); 27 | return this.networkClient.get(`${pathSegment}/${id}`); 28 | } 29 | 30 | /** 31 | * Retrieve the currently authenticated organization. 32 | * 33 | * @since 3.2.0 34 | * @see https://docs.mollie.com/reference/v2/organizations-api/current-organization 35 | */ 36 | public getCurrent(): Promise; 37 | public getCurrent(callback: Callback): void; 38 | public getCurrent() { 39 | if (renege(this, this.getCurrent, ...arguments)) return; 40 | return this.networkClient.get(`${pathSegment}/me`); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/binders/paymentLinks/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type PaymentLinkData } from '../../data/paymentLinks/data'; 2 | import { type IdempotencyParameter, type PaginationParameters, type ThrottlingParameter } from '../../types/parameters'; 3 | import type PickOptional from '../../types/PickOptional'; 4 | 5 | export type CreateParameters = Pick & 6 | PickOptional & { 7 | testmode?: boolean; 8 | } & IdempotencyParameter; 9 | 10 | export interface GetParameters { 11 | testmode?: boolean; 12 | } 13 | 14 | export type PageParameters = PaginationParameters & { 15 | profileId?: string; 16 | testmode?: boolean; 17 | }; 18 | 19 | export type UpdateParameters = Pick & 20 | PickOptional & { 21 | testmode?: boolean; 22 | }; 23 | 24 | export type IterateParameters = Omit & ThrottlingParameter; 25 | -------------------------------------------------------------------------------- /src/binders/payments/captures/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type CaptureData, type CaptureInclude } from '../../../data/payments/captures/data'; 2 | import type MaybeArray from '../../../types/MaybeArray'; 3 | import { type IdempotencyParameter, type PaginationParameters, type ThrottlingParameter } from '../../../types/parameters'; 4 | import type PickOptional from '../../../types/PickOptional'; 5 | 6 | interface ContextParameters { 7 | paymentId: string; 8 | } 9 | 10 | export type CreateParameters = ContextParameters & PickOptional & IdempotencyParameter; 11 | 12 | export type GetParameters = ContextParameters & { 13 | include?: MaybeArray; 14 | testmode?: boolean; 15 | }; 16 | 17 | export type PageParameters = ContextParameters & 18 | PaginationParameters & { 19 | include?: MaybeArray; 20 | testmode?: boolean; 21 | }; 22 | 23 | export type IterateParameters = Omit & ThrottlingParameter; 24 | -------------------------------------------------------------------------------- /src/binders/payments/chargebacks/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type ChargebackEmbed } from '../../../data/chargebacks/Chargeback'; 2 | import { type PaginationParameters, type ThrottlingParameter } from '../../../types/parameters'; 3 | 4 | interface ContextParameters { 5 | paymentId: string; 6 | } 7 | 8 | export type GetParameters = ContextParameters & { 9 | embed?: ChargebackEmbed[]; 10 | }; 11 | 12 | export type PageParameters = ContextParameters & 13 | PaginationParameters & { 14 | embed?: ChargebackEmbed[]; 15 | }; 16 | 17 | export type IterateParameters = Omit & ThrottlingParameter; 18 | -------------------------------------------------------------------------------- /src/binders/payments/orders/OrderPaymentsBinder.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../../communication/TransformingNetworkClient'; 2 | import { type PaymentData } from '../../../data/payments/data'; 3 | import type Payment from '../../../data/payments/Payment'; 4 | import assertWellFormedId from '../../../plumbing/assertWellFormedId'; 5 | import renege from '../../../plumbing/renege'; 6 | import type Callback from '../../../types/Callback'; 7 | import Binder from '../../Binder'; 8 | import { type CreateParameters } from './parameters'; 9 | 10 | function getPathSegments(orderId: string) { 11 | return `orders/${orderId}/payments`; 12 | } 13 | 14 | export default class OrderPaymentsBinder extends Binder { 15 | constructor(protected readonly networkClient: TransformingNetworkClient) { 16 | super(); 17 | } 18 | 19 | /** 20 | * An order has an automatically created payment that your customer can use to pay for the order. When the payment expires you can create a new payment for the order using this endpoint. A maximum 21 | * of 25 payments can be created for an order. 22 | * 23 | * A new payment can only be created while the status of the order is `created`, and when the status of the existing payment is either `expired`, `canceled` or `failed`. 24 | * 25 | * Note that order details (for example `amount` or `webhookUrl`) can not be changed using this endpoint. 26 | * 27 | * @since 3.1.0 28 | * @see https://docs.mollie.com/reference/v2/orders-api/create-order-payment 29 | */ 30 | public create(parameters: CreateParameters): Promise; 31 | public create(parameters: CreateParameters, callback: Callback): void; 32 | public create(parameters: CreateParameters) { 33 | if (renege(this, this.create, ...arguments)) return; 34 | const { orderId, ...data } = parameters; 35 | assertWellFormedId(orderId, 'order'); 36 | return this.networkClient.post(getPathSegments(orderId), data); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/binders/payments/orders/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type PaymentMethod } from '../../../data/global'; 2 | import { type PaymentData } from '../../../data/payments/data'; 3 | import type MaybeArray from '../../../types/MaybeArray'; 4 | import { type IdempotencyParameter } from '../../../types/parameters'; 5 | 6 | interface ContextParameters { 7 | orderId: string; 8 | testmode?: boolean; 9 | } 10 | 11 | export type CreateParameters = ContextParameters & 12 | Pick & { 13 | /** 14 | * Normally, a payment method screen is shown. However, when using this parameter, you can choose a specific payment method and your customer will skip the selection screen and is sent directly to 15 | * the chosen payment method. The parameter enables you to fully integrate the payment method selection into your website. 16 | * 17 | * You can also specify the methods in an array. By doing so we will still show the payment method selection screen but will only show the methods specified in the array. For example, you can use 18 | * this functionality to only show payment methods from a specific country to your customer `["bancontact", "belfius"]`. 19 | * 20 | * Possible values: `applepay` `bancontact` `banktransfer` `belfius` `creditcard` `directdebit` `eps` `giftcard` `giropay` `ideal` `in3` `kbc` `klarnapaylater` `klarnapaynow` `klarnasliceit` 21 | * `paypal` `paysafecard` `przelewy24` `sofort` 22 | * 23 | * @see https://docs.mollie.com/reference/v2/orders-api/create-order-payment?path=method#parameters 24 | */ 25 | method?: MaybeArray; 26 | /** 27 | * The ID of the customer for whom the payment is being created. This is used for recurring payments and single-click payments. 28 | * 29 | * @see https://docs.mollie.com/reference/v2/orders-api/create-order-payment?path=customerId#parameters 30 | */ 31 | customerId?: string; 32 | } & IdempotencyParameter; 33 | -------------------------------------------------------------------------------- /src/binders/payments/refunds/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type RefundData, type RefundEmbed } from '../../../data/refunds/data'; 2 | import { type IdempotencyParameter, type PaginationParameters, type ThrottlingParameter } from '../../../types/parameters'; 3 | import type PickOptional from '../../../types/PickOptional'; 4 | 5 | interface ContextParameters { 6 | paymentId: string; 7 | testmode?: boolean; 8 | } 9 | 10 | export type CreateParameters = ContextParameters & Pick & PickOptional & IdempotencyParameter; 11 | 12 | export type GetParameters = ContextParameters & { 13 | embed?: RefundEmbed[]; 14 | }; 15 | 16 | export type PageParameters = ContextParameters & 17 | PaginationParameters & { 18 | embed?: RefundEmbed[]; 19 | }; 20 | 21 | export type IterateParameters = Omit & ThrottlingParameter; 22 | 23 | export type CancelParameters = ContextParameters & IdempotencyParameter; 24 | -------------------------------------------------------------------------------- /src/binders/permissions/PermissionsBinder.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Permission from '../../data/permissions/Permission'; 3 | import { type PermissionData } from '../../data/permissions/Permission'; 4 | import alias from '../../plumbing/alias'; 5 | import renege from '../../plumbing/renege'; 6 | import type Callback from '../../types/Callback'; 7 | import Binder from '../Binder'; 8 | 9 | const pathSegment = 'permissions'; 10 | 11 | export default class PermissionsBinder extends Binder { 12 | constructor(protected readonly networkClient: TransformingNetworkClient) { 13 | super(); 14 | alias(this, { list: 'page' }); 15 | } 16 | 17 | /** 18 | * Retrieve the details on a specific permission, and see if the permission is granted to the current app access token. 19 | * 20 | * @since 3.2.0 21 | * @see https://docs.mollie.com/reference/v2/permissions-api/get-permission 22 | */ 23 | public get(id: string): Promise; 24 | public get(id: string, callback: Callback): void; 25 | public get(id: string) { 26 | if (renege(this, this.get, ...arguments)) return; 27 | return this.networkClient.get(`${pathSegment}/${id}`); 28 | } 29 | 30 | /** 31 | * List all permissions available with the current app access token. The list is not paginated. 32 | * 33 | * @since 3.2.0 34 | * @see https://docs.mollie.com/reference/v2/permissions-api/list-permissions 35 | */ 36 | public list(): Promise; 37 | public list(callback: Callback): void; 38 | public list() { 39 | if (renege(this, this.list, ...arguments)) return; 40 | return this.networkClient.list(pathSegment, 'permissions', {}); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/binders/profiles/giftcardIssuers/ProfileGiftcardIssuersBinder.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../../communication/TransformingNetworkClient'; 2 | import { type IssuerData } from '../../../data/issuer/IssuerModel'; 3 | import type IssuerModel from '../../../data/issuer/IssuerModel'; 4 | import renege from '../../../plumbing/renege'; 5 | import assertWellFormedId from '../../../plumbing/assertWellFormedId'; 6 | import type Callback from '../../../types/Callback'; 7 | import Binder from '../../Binder'; 8 | import { type Parameters } from './parameters'; 9 | 10 | function getPathSegments(profileId: string) { 11 | return `profiles/${profileId}/methods/giftcard/issuers`; 12 | } 13 | 14 | export default class ProfileGiftcardIssuersBinder extends Binder { 15 | constructor(protected readonly networkClient: TransformingNetworkClient) { 16 | super(); 17 | } 18 | 19 | /** 20 | * Enable a gift card issuer on a specific or authenticated profile to use it with payments. 21 | * 22 | * @since 3.7.0 23 | * @see https://docs.mollie.com/reference/v2/profiles-api/enable-gift-card-issuer 24 | */ 25 | public enable(parameters: Parameters): Promise; 26 | public enable(parameters: Parameters, callback: Callback): void; 27 | public enable(parameters: Parameters) { 28 | if (renege(this, this.enable, ...arguments)) return; 29 | const { id, profileId, ...data } = parameters; 30 | assertWellFormedId(profileId, 'profile'); 31 | return this.networkClient.post(`${getPathSegments(profileId)}/${id}`, data); 32 | } 33 | 34 | /** 35 | * Disable a gift card issuer on a specific or authenticated profile. 36 | * 37 | * @since 3.7.0 38 | * @see https://docs.mollie.com/reference/v2/profiles-api/disable-gift-card-issuer 39 | */ 40 | public disable(parameters: Parameters): Promise; 41 | public disable(parameters: Parameters, callback: Callback): void; 42 | public disable(parameters: Parameters) { 43 | if (renege(this, this.disable, ...arguments)) return; 44 | const { id, profileId, ...context } = parameters; 45 | assertWellFormedId(profileId, 'profile'); 46 | return this.networkClient.delete(`${getPathSegments(profileId)}/${id}`, context); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/binders/profiles/giftcardIssuers/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type IdempotencyParameter } from '../../../types/parameters'; 2 | 3 | export interface Parameters extends IdempotencyParameter { 4 | /** 5 | * The ID of the profile, for example `pfl_v9hTwCvYqw`. 6 | */ 7 | profileId: string; 8 | /** 9 | * The ID of the issuer, for example `festivalcadeau`. 10 | */ 11 | id: string; 12 | } 13 | -------------------------------------------------------------------------------- /src/binders/profiles/methods/ProfileMethodsBinder.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../../communication/TransformingNetworkClient'; 2 | import { type MethodData } from '../../../data/methods/data'; 3 | import type Method from '../../../data/methods/Method'; 4 | import renege from '../../../plumbing/renege'; 5 | import assertWellFormedId from '../../../plumbing/assertWellFormedId'; 6 | import type Callback from '../../../types/Callback'; 7 | import Binder from '../../Binder'; 8 | import { type Parameters } from './parameters'; 9 | 10 | function getPathSegments(profileId: string) { 11 | return `profiles/${profileId}/methods`; 12 | } 13 | 14 | export default class ProfileMethodsBinder extends Binder { 15 | constructor(protected readonly networkClient: TransformingNetworkClient) { 16 | super(); 17 | } 18 | 19 | /** 20 | * Enable a payment method on a specific or authenticated profile to use it with payments. 21 | * 22 | * The payment method `vouchers` cannot be enabled via this API. Instead, refer to /reference/v2/profiles-api/enable-voucher-issuer. 23 | * 24 | * @since 3.7.0 25 | * @see https://docs.mollie.com/reference/v2/profiles-api/enable-method 26 | */ 27 | public enable(parameters: Parameters): Promise; 28 | public enable(parameters: Parameters, callback: Callback): void; 29 | public enable(parameters: Parameters) { 30 | if (renege(this, this.enable, ...arguments)) return; 31 | const { id, profileId, ...data } = parameters; 32 | assertWellFormedId(profileId, 'profile'); 33 | return this.networkClient.post(`${getPathSegments(profileId)}/${id}`, data); 34 | } 35 | 36 | /** 37 | * Disable a payment method on a specific or authenticated profile. 38 | * 39 | * @since 3.7.0 40 | * @see https://docs.mollie.com/reference/v2/profiles-api/disable-method 41 | */ 42 | public disable(parameters: Parameters): Promise; 43 | public disable(parameters: Parameters, callback: Callback): void; 44 | public disable(parameters: Parameters) { 45 | if (renege(this, this.disable, ...arguments)) return; 46 | const { id, profileId, ...context } = parameters; 47 | assertWellFormedId(profileId, 'profile'); 48 | return this.networkClient.delete(`${getPathSegments(profileId)}/${id}`, context); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/binders/profiles/methods/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type PaymentMethod } from '../../../types'; 2 | import { type IdempotencyParameter } from '../../../types/parameters'; 3 | 4 | export interface Parameters extends IdempotencyParameter { 5 | /** 6 | * The ID of the profile, for example `pfl_v9hTwCvYqw`. 7 | */ 8 | profileId: string; 9 | /** 10 | * The ID of the method, for example `ideal`. 11 | */ 12 | id: `${PaymentMethod}`; 13 | } 14 | -------------------------------------------------------------------------------- /src/binders/profiles/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type ProfileData } from '../../data/profiles/data'; 2 | import { type IdempotencyParameter, type PaginationParameters, type ThrottlingParameter } from '../../types/parameters'; 3 | import type PickOptional from '../../types/PickOptional'; 4 | 5 | export type CreateParameters = Pick & PickOptional & IdempotencyParameter; 6 | 7 | export type PageParameters = PaginationParameters; 8 | 9 | export type IterateParameters = Omit & ThrottlingParameter; 10 | 11 | export type UpdateParameters = PickOptional; 12 | 13 | export type DeleteParameters = IdempotencyParameter; 14 | -------------------------------------------------------------------------------- /src/binders/profiles/voucherIssuers/ProfileVoucherIssuersBinder.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../../communication/TransformingNetworkClient'; 2 | import type IssuerModel from '../../../data/issuer/IssuerModel'; 3 | import { type IssuerData } from '../../../data/issuer/IssuerModel'; 4 | import assertWellFormedId from '../../../plumbing/assertWellFormedId'; 5 | import renege from '../../../plumbing/renege'; 6 | import type Callback from '../../../types/Callback'; 7 | import Binder from '../../Binder'; 8 | import { type CreateParameters, type Parameters } from './parameters'; 9 | 10 | function getPathSegments(profileId: string) { 11 | return `profiles/${profileId}/methods/voucher/issuers`; 12 | } 13 | 14 | export default class ProfileVoucherIssuersBinder extends Binder { 15 | constructor(protected readonly networkClient: TransformingNetworkClient) { 16 | super(); 17 | } 18 | 19 | /** 20 | * Enable a voucher issuer on a specific or authenticated profile to use it with payments. 21 | * 22 | * @since 3.7.0 23 | * @see https://docs.mollie.com/reference/v2/profiles-api/enable-voucher-issuer 24 | */ 25 | public enable(parameters: CreateParameters): Promise; 26 | public enable(parameters: CreateParameters, callback: Callback): void; 27 | public enable(parameters: CreateParameters) { 28 | if (renege(this, this.enable, ...arguments)) return; 29 | const { id, profileId, ...data } = parameters; 30 | assertWellFormedId(profileId, 'profile'); 31 | return this.networkClient.post(`${getPathSegments(profileId)}/${id}`, data); 32 | } 33 | 34 | /** 35 | * Disable a voucher issuer on a specific or authenticated profile. 36 | * 37 | * @since 3.7.0 38 | * @see https://docs.mollie.com/reference/v2/profiles-api/disable-voucher-issuer 39 | */ 40 | public disable(parameters: Parameters): Promise; 41 | public disable(parameters: Parameters, callback: Callback): void; 42 | public disable(parameters: Parameters) { 43 | if (renege(this, this.disable, ...arguments)) return; 44 | const { id, profileId, ...context } = parameters; 45 | assertWellFormedId(profileId, 'profile'); 46 | return this.networkClient.delete(`${getPathSegments(profileId)}/${id}`, context); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/binders/profiles/voucherIssuers/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type IdempotencyParameter } from '../../../types/parameters'; 2 | 3 | export interface Parameters extends IdempotencyParameter { 4 | /** 5 | * The ID of the profile, for example `pfl_v9hTwCvYqw`. 6 | */ 7 | profileId: string; 8 | /** 9 | * The ID of the issuer, for example `appetiz`. 10 | */ 11 | id: string; 12 | } 13 | 14 | export type CreateParameters = Parameters & { 15 | /** 16 | * The contract id of the related contractor. For the first call that will be made to an issuer of the contractor, this field is required. You do not have to provide the same contract id for other 17 | * issuers of the same contractor. Update of the contract ID will be possible through making the same call again with different contract ID value until the contract id is approved by the contractor. 18 | * 19 | * @see https://docs.mollie.com/reference/v2/profiles-api/enable-voucher-issuer?path=contractId#parameters 20 | */ 21 | contractId?: string; 22 | }; 23 | -------------------------------------------------------------------------------- /src/binders/refunds/RefundsBinder.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Page from '../../data/page/Page'; 3 | import { type RefundData } from '../../data/refunds/data'; 4 | import type Refund from '../../data/refunds/Refund'; 5 | import alias from '../../plumbing/alias'; 6 | import renege from '../../plumbing/renege'; 7 | import type Callback from '../../types/Callback'; 8 | import Binder from '../Binder'; 9 | import { type IterateParameters, type PageParameters } from './parameters'; 10 | 11 | const pathSegment = 'refunds'; 12 | 13 | export default class RefundsBinder extends Binder { 14 | constructor(protected readonly networkClient: TransformingNetworkClient) { 15 | super(); 16 | alias(this, { page: ['all', 'list'] }); 17 | } 18 | 19 | /** 20 | * Retrieve a list of all of your refunds. 21 | * 22 | * The results are paginated. See pagination for more information. 23 | * 24 | * @since 3.0.0 25 | * @see https://docs.mollie.com/reference/v2/refunds-api/list-refunds 26 | */ 27 | public page(parameters?: PageParameters): Promise>; 28 | public page(parameters: PageParameters, callback: Callback>): void; 29 | public page(parameters: PageParameters = {}) { 30 | if (renege(this, this.page, ...arguments)) return; 31 | return this.networkClient.page(pathSegment, 'refunds', parameters).then(result => this.injectPaginationHelpers(result, this.page, parameters)); 32 | } 33 | 34 | /** 35 | * Retrieve a list of all of your refunds. 36 | * 37 | * The results are paginated. See pagination for more information. 38 | * 39 | * @since 3.6.0 40 | * @see https://docs.mollie.com/reference/v2/refunds-api/list-refunds 41 | */ 42 | public iterate(parameters?: IterateParameters) { 43 | const { valuesPerMinute, ...query } = parameters ?? {}; 44 | return this.networkClient.iterate(pathSegment, 'refunds', query, valuesPerMinute); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/binders/refunds/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type PaginationParameters, type ThrottlingParameter } from '../../types/parameters'; 2 | 3 | export type PageParameters = PaginationParameters & { 4 | profileId?: string; 5 | testmode?: boolean; 6 | }; 7 | 8 | export type IterateParameters = Omit & ThrottlingParameter; 9 | -------------------------------------------------------------------------------- /src/binders/settlements/captures/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type ThrottlingParameter } from '../../../types/parameters'; 2 | import { type PageParameters as CapturePageParameters } from '../../payments/captures/parameters'; 3 | 4 | export type PageParameters = Omit & { 5 | settlementId: string; 6 | }; 7 | 8 | export type IterateParameters = Omit & ThrottlingParameter; 9 | -------------------------------------------------------------------------------- /src/binders/settlements/chargebacks/SettlementChargebacksBinder.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../../communication/TransformingNetworkClient'; 2 | import type Chargeback from '../../../data/chargebacks/Chargeback'; 3 | import { type ChargebackData } from '../../../data/chargebacks/Chargeback'; 4 | import type Page from '../../../data/page/Page'; 5 | import renege from '../../../plumbing/renege'; 6 | import type Callback from '../../../types/Callback'; 7 | import Binder from '../../Binder'; 8 | import { type IterateParameters, type PageParameters } from './parameters'; 9 | 10 | export function getPathSegments(settlementId: string) { 11 | return `settlements/${settlementId}/chargebacks`; 12 | } 13 | 14 | export default class SettlementChargebacksBinder extends Binder { 15 | constructor(protected readonly networkClient: TransformingNetworkClient) { 16 | super(); 17 | } 18 | 19 | /** 20 | * Retrieve all chargebacks included in a settlement. 21 | * 22 | * @since 3.7.0 23 | * @see https://docs.mollie.com/reference/v2/settlements-api/list-settlement-chargebacks 24 | */ 25 | public page(parameters: PageParameters): Promise>; 26 | public page(parameters: PageParameters, callback: Callback>): void; 27 | public page(parameters: PageParameters) { 28 | if (renege(this, this.page, ...arguments)) return; 29 | const { settlementId, ...query } = parameters; 30 | return this.networkClient.page(getPathSegments(settlementId), 'chargebacks', query).then(result => this.injectPaginationHelpers(result, this.page, parameters)); 31 | } 32 | 33 | /** 34 | * Retrieve all chargebacks included in a settlement. 35 | * 36 | * @since 3.7.0 37 | * @see https://docs.mollie.com/reference/v2/settlements-api/list-settlement-chargebacks 38 | */ 39 | public iterate(parameters: IterateParameters) { 40 | const { settlementId, valuesPerMinute, ...query } = parameters; 41 | return this.networkClient.iterate(getPathSegments(settlementId), 'chargebacks', query, valuesPerMinute); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/binders/settlements/chargebacks/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type ThrottlingParameter } from '../../../types/parameters'; 2 | import { type PageParameters as ChargebacksPageParameters } from '../../chargebacks/parameters'; 3 | 4 | export type PageParameters = ChargebacksPageParameters & { 5 | settlementId: string; 6 | }; 7 | 8 | export type IterateParameters = Omit & ThrottlingParameter; 9 | -------------------------------------------------------------------------------- /src/binders/settlements/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type PaginationParameters, type ThrottlingParameter } from '../../types/parameters'; 2 | 3 | export type PageParameters = PaginationParameters; 4 | 5 | export type IterateParameters = Omit & ThrottlingParameter; 6 | -------------------------------------------------------------------------------- /src/binders/settlements/payments/SettlementPaymentsBinder.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../../communication/TransformingNetworkClient'; 2 | import type Page from '../../../data/page/Page'; 3 | import { type PaymentData } from '../../../data/payments/data'; 4 | import type Payment from '../../../data/payments/Payment'; 5 | import renege from '../../../plumbing/renege'; 6 | import type Callback from '../../../types/Callback'; 7 | import Binder from '../../Binder'; 8 | import { type IterateParameters, type PageParameters } from './parameters'; 9 | 10 | export function getPathSegments(settlementId: string) { 11 | return `settlements/${settlementId}/payments`; 12 | } 13 | 14 | export default class SettlementPaymentsBinder extends Binder { 15 | constructor(protected readonly networkClient: TransformingNetworkClient) { 16 | super(); 17 | } 18 | 19 | /** 20 | * Retrieve all Payments included in a Settlement. 21 | * 22 | * Note that payments for Klarna payment methods are not listed in here. These payment methods are settled using captures. To retrieve the captures, use the List settlement captures endpoint. 23 | * 24 | * @since 3.7.0 25 | * @see https://docs.mollie.com/reference/v2/settlements-api/list-settlement-payments 26 | */ 27 | public page(parameters: PageParameters): Promise>; 28 | public page(parameters: PageParameters, callback: Callback>): void; 29 | public page(parameters: PageParameters) { 30 | if (renege(this, this.page, ...arguments)) return; 31 | const { settlementId, ...query } = parameters; 32 | return this.networkClient.page(getPathSegments(settlementId), 'payments', query).then(result => this.injectPaginationHelpers(result, this.page, parameters)); 33 | } 34 | 35 | /** 36 | * Retrieve all Payments included in a Settlement. 37 | * 38 | * Note that payments for Klarna payment methods are not listed in here. These payment methods are settled using captures. To retrieve the captures, use the List settlement captures endpoint. 39 | * 40 | * @since 3.7.0 41 | * @see https://docs.mollie.com/reference/v2/settlements-api/list-settlement-payments 42 | */ 43 | public iterate(parameters: IterateParameters) { 44 | const { settlementId, valuesPerMinute, ...query } = parameters; 45 | return this.networkClient.iterate(getPathSegments(settlementId), 'payments', query, valuesPerMinute); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/binders/settlements/payments/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type ThrottlingParameter } from '../../../types/parameters'; 2 | import { type PageParameters as PaymentPageParameters } from '../../payments/parameters'; 3 | 4 | export type PageParameters = PaymentPageParameters & { 5 | settlementId: string; 6 | }; 7 | 8 | export type IterateParameters = Omit & ThrottlingParameter; 9 | -------------------------------------------------------------------------------- /src/binders/settlements/refunds/SettlementRefundsBinder.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../../communication/TransformingNetworkClient'; 2 | import type Page from '../../../data/page/Page'; 3 | import { type RefundData } from '../../../data/refunds/data'; 4 | import type Refund from '../../../data/refunds/Refund'; 5 | import renege from '../../../plumbing/renege'; 6 | import type Callback from '../../../types/Callback'; 7 | import Binder from '../../Binder'; 8 | import { type IterateParameters, type PageParameters } from './parameters'; 9 | 10 | export function getPathSegments(settlementId: string) { 11 | return `settlements/${settlementId}/refunds`; 12 | } 13 | 14 | export default class SettlementRefundsBinder extends Binder { 15 | constructor(protected readonly networkClient: TransformingNetworkClient) { 16 | super(); 17 | } 18 | 19 | /** 20 | * Retrieve all refunds included in a settlement. 21 | * 22 | * @since 3.7.0 23 | * @see https://docs.mollie.com/reference/v2/settlements-api/list-settlement-refunds 24 | */ 25 | public page(parameters: PageParameters): Promise>; 26 | public page(parameters: PageParameters, callback: Callback>): void; 27 | public page(parameters: PageParameters) { 28 | if (renege(this, this.page, ...arguments)) return; 29 | const { settlementId, ...query } = parameters; 30 | return this.networkClient.page(getPathSegments(settlementId), 'refunds', query).then(result => this.injectPaginationHelpers(result, this.page, parameters)); 31 | } 32 | 33 | /** 34 | * Retrieve all refunds included in a settlement. 35 | * 36 | * @since 3.7.0 37 | * @see https://docs.mollie.com/reference/v2/settlements-api/list-settlement-refunds 38 | */ 39 | public iterate(parameters: IterateParameters) { 40 | const { settlementId, valuesPerMinute, ...query } = parameters; 41 | return this.networkClient.iterate(getPathSegments(settlementId), 'refunds', query, valuesPerMinute); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/binders/settlements/refunds/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type ThrottlingParameter } from '../../../types/parameters'; 2 | import { type PageParameters as RefundsPageParameters } from '../../refunds/parameters'; 3 | 4 | export type PageParameters = RefundsPageParameters & { 5 | settlementId: string; 6 | }; 7 | 8 | export type IterateParameters = Omit & ThrottlingParameter; 9 | -------------------------------------------------------------------------------- /src/binders/subscriptions/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type PaginationParameters, type ThrottlingParameter } from '../../types/parameters'; 2 | 3 | export type PageParameters = PaginationParameters & { 4 | profileId?: string; 5 | testmode?: boolean; 6 | }; 7 | 8 | export type IterateParameters = Omit & ThrottlingParameter; 9 | -------------------------------------------------------------------------------- /src/binders/subscriptions/payments/parameters.ts: -------------------------------------------------------------------------------- 1 | import { type PaginationParameters, type ThrottlingParameter } from '../../../types/parameters'; 2 | 3 | interface ContextParameters { 4 | testmode?: boolean; 5 | customerId: string; 6 | subscriptionId: string; 7 | } 8 | 9 | export type PageParameters = ContextParameters & PaginationParameters; 10 | 11 | export type IterateParameters = Omit & ThrottlingParameter; 12 | -------------------------------------------------------------------------------- /src/binders/terminals/parameters.ts: -------------------------------------------------------------------------------- 1 | import { PaginationParameters, ThrottlingParameter } from '../../types/parameters'; 2 | 3 | export type PageParameters = PaginationParameters & { 4 | testmode?: boolean; 5 | }; 6 | 7 | export type IterateParameters = Omit & ThrottlingParameter; 8 | -------------------------------------------------------------------------------- /src/certs.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.pem' { 2 | const content: string; 3 | export default content; 4 | } 5 | -------------------------------------------------------------------------------- /src/communication/breakUrl.ts: -------------------------------------------------------------------------------- 1 | // The following line is only necessary for Node.js < 10.0.0, which we only secretly support. Should we ever drop that support completely, we can remove this import. 2 | import { URL } from 'url'; 3 | 4 | import buildFromEntries from '../plumbing/buildFromEntries'; 5 | 6 | /** 7 | * Breaks the passed URL into a pair of the pathname+origin and the search parameters. For example: 8 | * `'https://example.com?id=5'` is converted to `['https://example.com', { id: 5 }]` and `'https://example.com'` is 9 | * converted to `['https://example.com', {}]`. 10 | * 11 | * If multiple parameters have the same key (`'https://example.com?id=5&id=6'`), exactly one of them will be 12 | * represented in the returned search parameters object. 13 | * 14 | * The passed URL is expceted not to contain a hash. 15 | * 16 | * This function is designed to be the reverse of `buildUrl`. However, as that function accepts search parameters which 17 | * are numbers, arrays, or objects, and includes them in the URL. The type information of the search parameters is lost 18 | * in the process, and not recovered by this function. For example: 19 | * `breakUrl(buildUrl('https://example.com', { id: 5 }))` is converted to `['https://example.com', { id: '5' }]` (note 20 | * how 5 is now a string). 21 | */ 22 | export default function breakUrl(input: string) { 23 | const parsed = new URL(input); 24 | return [buildFromEntries(parsed.searchParams), ((parsed.search = ''), parsed.toString())].reverse() as [string, Record]; 25 | } 26 | -------------------------------------------------------------------------------- /src/communication/buildUrl.ts: -------------------------------------------------------------------------------- 1 | // The following line is only necessary for Node.js < 10.0.0, which we only secretly support. Should we ever drop that support completely, we can remove this import. 2 | import { URLSearchParams } from 'url'; 3 | 4 | import { apply, runIf } from 'ruply'; 5 | 6 | import type Maybe from '../types/Maybe'; 7 | import type MaybeArray from '../types/MaybeArray'; 8 | 9 | export type SearchParameters = Record; 10 | 11 | /** 12 | * Builds a URL from the passed origin+pathname and search parameters. For example: `https://example.com` and 13 | * `{ id: 5 }` is converted to `https://example.com?id=5`; while `https://example.com` and `undefined` is left as 14 | * `https://example.com`. 15 | * 16 | * Note that the origin+pathname is used verbatim. The origin is optional and a relative URL can be built by omitting 17 | * it. 18 | * 19 | * As expected by the Mollie API: 20 | * * search parameters which are arrays are joined with commas (`{ array: [1, 2] }` becomes `?array=1,2`), and 21 | * * search parameters which are objects (but not arrays) are flattened (`{ object: { key: 'value' } }` becomes 22 | * `?object[key]=value`). 23 | */ 24 | export default function buildUrl(originAndPathname: string, searchParameters?: SearchParameters): string { 25 | const searchEntries = (runIf(searchParameters, Object.entries) ?? []) as [string, Maybe>][]; 26 | if (searchEntries.length == 0) { 27 | return originAndPathname; 28 | } 29 | return `${originAndPathname}?${new URLSearchParams( 30 | apply({} as Record>, flattenedEntries => { 31 | for (const [key, value] of searchEntries) { 32 | if (value == undefined) { 33 | continue; 34 | } 35 | if (typeof value == 'object' && !Array.isArray(value)) { 36 | for (const [innerKey, innerValue] of Object.entries(value)) { 37 | flattenedEntries[`${key}[${innerKey}]`] = String(innerValue); 38 | } 39 | } /* if (typeof value != 'object' || Array.isArray(value)) */ else { 40 | flattenedEntries[key] = String(value); 41 | } 42 | } 43 | }), 44 | )}`; 45 | } 46 | -------------------------------------------------------------------------------- /src/communication/dromedaryCase.ts: -------------------------------------------------------------------------------- 1 | // (Converts any character after a word boundary to upper case, except for the first character in the string.) 2 | const firstIteration = [/(?!^)\b\w/g, (character: string) => character.toUpperCase()] as const; 3 | // (Removes all whitespace.) 4 | const secondIteration = [/\s+/g, ''] as const; 5 | /** 6 | * Converts `'rockenberg commerce'` to `'rockenbergCommerce'`. 7 | */ 8 | export default function dromedaryCase(input: string) { 9 | return input.replace(...firstIteration).replace(...secondIteration); 10 | } 11 | -------------------------------------------------------------------------------- /src/data/Helper.ts: -------------------------------------------------------------------------------- 1 | import { inspect, type InspectOptionsStylized } from 'util'; 2 | import breakUrl from '../communication/breakUrl'; 3 | import type TransformingNetworkClient from '../communication/TransformingNetworkClient'; 4 | import buildFromEntries from '../plumbing/buildFromEntries'; 5 | import capitalize from '../plumbing/capitalize'; 6 | import renege from '../plumbing/renege'; 7 | import type Callback from '../types/Callback'; 8 | import type Maybe from '../types/Maybe'; 9 | import { type Links } from './global'; 10 | import type Model from './Model'; 11 | 12 | const stringRepresentationBlacklist = new Set(['resource', 'id', '_links', '_embedded']); 13 | 14 | /** 15 | * Returns a human-readable representation of the passed subject. 16 | */ 17 | function convertToString(subject: Model, tag: string, depth: number, options: InspectOptionsStylized) { 18 | const parts = [tag]; 19 | if (subject.id != undefined) { 20 | parts.push(subject.id); 21 | } 22 | if (depth < 0) { 23 | return options.stylize(`[${parts.join(' ')}]`, 'special'); 24 | } 25 | parts.push(inspect(buildFromEntries(Object.entries(subject).filter(([key]) => stringRepresentationBlacklist.has(key) === false)), { ...options, depth: 1, sorted: true })); 26 | return parts.join(' '); 27 | } 28 | 29 | export default class Helper>, U> { 30 | constructor( 31 | protected readonly networkClient: TransformingNetworkClient, 32 | protected readonly links: Links, 33 | ) {} 34 | 35 | public refresh(): Promise; 36 | public refresh(callback: Callback): void; 37 | public refresh() { 38 | if (renege(this, this.refresh, ...arguments)) return; 39 | return this.networkClient.get(...breakUrl(this.links.self.href)); 40 | } 41 | 42 | public get [Symbol.toStringTag]() { 43 | return capitalize((this as unknown as Model).resource); 44 | } 45 | 46 | public [inspect.custom](this: Helper, any> & Model, depth: number, options: InspectOptionsStylized) { 47 | return convertToString(this, this[Symbol.toStringTag], depth, options); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/data/Issuer.ts: -------------------------------------------------------------------------------- 1 | export type IdealIssuer = string; 2 | 3 | export type GiftcardIssuer = 4 | | 'beautycadeaukaart' 5 | | 'bloemencadeaukaart' 6 | | 'bloemplantgiftcard' 7 | | 'boekenbon' 8 | | 'decadeaukaart' 9 | | 'delokalecadeaukaart' 10 | | 'dinercadeau' 11 | | 'doenkadotickets' 12 | | 'fashioncheque' 13 | | 'festivalcadeau' 14 | | 'good4fun' 15 | | 'huistuincadeaukaart' 16 | | 'jewelcard' 17 | | 'kluscadeau' 18 | | 'kunstencultuurcadeaukaart' 19 | | 'nationalebioscoopbon' 20 | | 'nationaleentertainmentcard' 21 | | 'nationalegolfbon' 22 | | 'ohmygood' 23 | | 'podiumcadeaukaart' 24 | | 'reiscadeau' 25 | | 'restaurantcadeau' 26 | | 'sodexosportculturepass' 27 | | 'sportenfitcadeau' 28 | | 'sustainablefashion' 29 | | 'travelcheq' 30 | | 'vvvgiftcard' 31 | | 'vvvdinercheque' 32 | | 'vvvlekkerweg' 33 | | 'webshopgiftcard' 34 | | 'wijncadeaukaart' 35 | | 'yourgift'; 36 | 37 | export type KbcIssuer = 'kbc' | 'cbc'; 38 | 39 | type VoucherIssuer = string; 40 | 41 | export type Issuer = IdealIssuer | GiftcardIssuer | KbcIssuer | VoucherIssuer; 42 | -------------------------------------------------------------------------------- /src/data/Model.ts: -------------------------------------------------------------------------------- 1 | import type Maybe from '../types/Maybe'; 2 | 3 | export default interface Model = string> { 4 | /** 5 | * Indicates the kind of entity this is. 6 | */ 7 | resource: R; 8 | /** 9 | * The unique identifier for this entity. 10 | */ 11 | id: I; 12 | } 13 | -------------------------------------------------------------------------------- /src/data/applePaySession/ApplePaySession.ts: -------------------------------------------------------------------------------- 1 | export interface ApplePaySessionData { 2 | epochTimestamp: number; 3 | expiresAt: number; 4 | merchantSessionIdentifier: string; 5 | nonce: string; 6 | merchantIdentifier: string; 7 | domainName: string; 8 | displayName: string; 9 | signature: string; 10 | } 11 | 12 | type ApplePaySession = Readonly; 13 | 14 | export default ApplePaySession; 15 | -------------------------------------------------------------------------------- /src/data/chargebacks/ChargebackHelper.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import breakUrl from '../../communication/breakUrl'; 3 | import renege from '../../plumbing/renege'; 4 | import resolveIf from '../../plumbing/resolveIf'; 5 | import type Callback from '../../types/Callback'; 6 | import Helper from '../Helper'; 7 | import type Payment from '../payments/Payment'; 8 | import { type PaymentData } from '../payments/data'; 9 | import type Chargeback from './Chargeback'; 10 | import { type ChargebackData } from './Chargeback'; 11 | 12 | export default class ChargebackHelper extends Helper { 13 | constructor( 14 | networkClient: TransformingNetworkClient, 15 | protected readonly links: ChargebackData['_links'], 16 | protected readonly embedded: ChargebackData['_embedded'], 17 | ) { 18 | super(networkClient, links); 19 | } 20 | 21 | /** 22 | * Returns the payment this chargeback was issued for. 23 | * 24 | * @since 3.6.0 25 | */ 26 | public getPayment(): Promise; 27 | public getPayment(callback: Callback>): void; 28 | public getPayment() { 29 | if (renege(this, this.getPayment, ...arguments)) return; 30 | return resolveIf(this.embedded?.payment) ?? this.networkClient.get(...breakUrl(this.links.payment.href)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/data/customers/mandates/Mandate.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../../communication/TransformingNetworkClient'; 2 | import type Seal from '../../../types/Seal'; 3 | import { type MandateData } from './data'; 4 | import MandateHelper from './MandateHelper'; 5 | 6 | type Mandate = Seal; 7 | 8 | export default Mandate; 9 | 10 | export function transform(networkClient: TransformingNetworkClient, input: MandateData): Mandate { 11 | return Object.assign(Object.create(new MandateHelper(networkClient, input._links)), input); 12 | } 13 | -------------------------------------------------------------------------------- /src/data/customers/mandates/MandateHelper.ts: -------------------------------------------------------------------------------- 1 | import breakUrl from '../../../communication/breakUrl'; 2 | import type TransformingNetworkClient from '../../../communication/TransformingNetworkClient'; 3 | import renege from '../../../plumbing/renege'; 4 | import type Callback from '../../../types/Callback'; 5 | import Helper from '../../Helper'; 6 | import type Customer from '../Customer'; 7 | import { type CustomerData } from '../Customer'; 8 | import { type MandateData } from './data'; 9 | import type Mandate from './Mandate'; 10 | 11 | export default class MandateHelper extends Helper { 12 | constructor( 13 | networkClient: TransformingNetworkClient, 14 | protected readonly links: MandateData['_links'], 15 | ) { 16 | super(networkClient, links); 17 | } 18 | 19 | /** 20 | * Returns the payments belonging to the customer. 21 | * 22 | * @since 3.6.0 23 | */ 24 | public getCustomer(): Promise; 25 | public getCustomer(callback: Callback): void; 26 | public getCustomer() { 27 | if (renege(this, this.getCustomer, ...arguments)) return; 28 | return this.networkClient.get(...breakUrl(this.links.customer.href)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/data/issuer/IssuerModel.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Seal from '../../types/Seal'; 3 | import { type Links } from '../global'; 4 | import Helper from '../Helper'; 5 | import type Model from '../Model'; 6 | 7 | export interface IssuerData extends Model<'issuer'> { 8 | /** 9 | * The full name of the gift card or voucher issuer. 10 | */ 11 | description: string; 12 | /** 13 | * The status that the issuer is in. 14 | * 15 | * Possible values: 16 | * 17 | * - `activated`: The issuer is activated and ready for use. 18 | * - `pending-issuer`: Activation of this issuer relies on you taking action with the issuer itself. 19 | * 20 | * @see https://docs.mollie.com/reference/v2/profiles-api/enable-gift-card-issuer?path=status#response 21 | */ 22 | status: 'activated' | 'pending-issuer'; 23 | /** 24 | * An object with contractor information. 25 | * 26 | * @see https://docs.mollie.com/reference/v2/profiles-api/enable-voucher-issuer?path=contractor#response 27 | */ 28 | contractor?: { id: string; name: string; contractId: string }; 29 | _links: Links; 30 | } 31 | 32 | type IssuerModel = Seal>; 33 | 34 | export default IssuerModel; 35 | 36 | export function transform(networkClient: TransformingNetworkClient, input: IssuerData): IssuerModel { 37 | return Object.assign(Object.create(new Helper(networkClient, input._links)), input); 38 | } 39 | -------------------------------------------------------------------------------- /src/data/methods/Method.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Seal from '../../types/Seal'; 3 | import { type MethodData } from './data'; 4 | import MethodHelper from './MethodHelper'; 5 | 6 | type Method = Seal; 7 | 8 | export default Method; 9 | 10 | export function transform(networkClient: TransformingNetworkClient, input: MethodData): Method { 11 | return Object.assign(Object.create(new MethodHelper(networkClient, input._links)), input); 12 | } 13 | -------------------------------------------------------------------------------- /src/data/methods/MethodHelper.ts: -------------------------------------------------------------------------------- 1 | import ApiError from '../../errors/ApiError'; 2 | import Helper from '../Helper'; 3 | import { type MethodData, MethodImageSize } from './data'; 4 | import type Method from './Method'; 5 | 6 | export default class MethodHelper extends Helper { 7 | /** 8 | * The URLs of images representing the payment method. 9 | * 10 | * @since 2.0.0 11 | * @since 3.0.0 SVG support 12 | * @see https://docs.mollie.com/reference/v2/methods-api/get-method?path=image#response 13 | */ 14 | public getImage(this: MethodData, size: MethodImageSize | '1x' | '2x' = MethodImageSize.size2x): string { 15 | switch (size) { 16 | case '1x': 17 | case MethodImageSize.size1x: 18 | return this.image[MethodImageSize.size1x]; 19 | case '2x': 20 | case MethodImageSize.size2x: 21 | return this.image[MethodImageSize.size2x]; 22 | case MethodImageSize.svg: 23 | return this.image[MethodImageSize.svg]; 24 | default: 25 | throw new ApiError(`Unexpected size: ${size}`); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/data/onboarding/Onboarding.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Seal from '../../types/Seal'; 3 | import { type OnboardingData } from './data'; 4 | import OnboardingHelper from './OnboardingHelper'; 5 | 6 | type Onboarding = Seal; 7 | 8 | export default Onboarding; 9 | 10 | export function transform(networkClient: TransformingNetworkClient, input: OnboardingData): Onboarding { 11 | return Object.assign(Object.create(new OnboardingHelper(networkClient, input._links)), input); 12 | } 13 | -------------------------------------------------------------------------------- /src/data/onboarding/OnboardingHelper.ts: -------------------------------------------------------------------------------- 1 | import breakUrl from '../../communication/breakUrl'; 2 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 3 | import renege from '../../plumbing/renege'; 4 | import type Callback from '../../types/Callback'; 5 | import Helper from '../Helper'; 6 | import type Organization from '../organizations/Organizations'; 7 | import { type OrganizationData } from '../organizations/Organizations'; 8 | import { type OnboardingData } from './data'; 9 | import type Onboarding from './Onboarding'; 10 | 11 | export default class OnboardingHelper extends Helper { 12 | constructor( 13 | networkClient: TransformingNetworkClient, 14 | protected readonly links: OnboardingData['_links'], 15 | ) { 16 | super(networkClient, links); 17 | } 18 | 19 | /** 20 | * Returns the organization. 21 | * 22 | * @since 3.6.0 23 | */ 24 | public getOrganization(): Promise; 25 | public getOrganization(callback: Callback): void; 26 | public getOrganization() { 27 | if (renege(this, this.getOrganization, ...arguments)) return; 28 | return this.networkClient.get(...breakUrl(this.links.organization.href)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/data/orders/Order.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Seal from '../../types/Seal'; 3 | import type Payment from '../payments/Payment'; 4 | import { transform as transformPayment } from '../payments/Payment'; 5 | import type Refund from '../refunds/Refund'; 6 | import { transform as transformRefund } from '../refunds/Refund'; 7 | import { type OrderData } from './data'; 8 | import OrderHelper from './OrderHelper'; 9 | import type OrderLine from './orderlines/OrderLine'; 10 | import { transform as transformOrderLine } from './orderlines/OrderLine'; 11 | import type Shipment from './shipments/Shipment'; 12 | import { transform as transformShipment } from './shipments/Shipment'; 13 | 14 | type Order = Seal< 15 | Omit & { 16 | lines: OrderLine[]; 17 | _embedded?: { 18 | payments?: Payment[]; 19 | refunds?: Refund[]; 20 | shipments?: Shipment[]; 21 | }; 22 | }, 23 | OrderHelper 24 | >; 25 | 26 | export default Order; 27 | 28 | export function transform(networkClient: TransformingNetworkClient, input: OrderData): Order { 29 | let _embedded: Order['_embedded']; 30 | if (input._embedded != undefined) { 31 | _embedded = {}; 32 | if (input._embedded.payments != undefined) { 33 | _embedded.payments = input._embedded.payments.map(transformPayment.bind(undefined, networkClient)); 34 | } 35 | if (input._embedded.refunds != undefined) { 36 | _embedded.refunds = input._embedded.refunds.map(transformRefund.bind(undefined, networkClient)); 37 | } 38 | if (input._embedded.shipments != undefined) { 39 | _embedded.shipments = input._embedded.shipments.map(transformShipment.bind(undefined, networkClient)); 40 | } 41 | } 42 | return Object.assign(Object.create(new OrderHelper(networkClient, input._links, _embedded)), input, { 43 | lines: input.lines.map(transformOrderLine), 44 | _embedded, 45 | }); 46 | } 47 | -------------------------------------------------------------------------------- /src/data/orders/shipments/ShipmentHelper.ts: -------------------------------------------------------------------------------- 1 | import breakUrl from '../../../communication/breakUrl'; 2 | import type TransformingNetworkClient from '../../../communication/TransformingNetworkClient'; 3 | import renege from '../../../plumbing/renege'; 4 | import type Callback from '../../../types/Callback'; 5 | import Helper from '../../Helper'; 6 | import type Shipment from '../../orders/shipments/Shipment'; 7 | import { type ShipmentData } from '../../orders/shipments/Shipment'; 8 | import { type OrderData } from '../data'; 9 | import type Order from '../Order'; 10 | 11 | export default class ShipmentHelper extends Helper { 12 | constructor( 13 | networkClient: TransformingNetworkClient, 14 | protected readonly links: ShipmentData['_links'], 15 | ) { 16 | super(networkClient, links); 17 | } 18 | 19 | /** 20 | * Returns the order this shipment was created for. 21 | * 22 | * @since 3.6.0 23 | */ 24 | public getOrder(): Promise; 25 | public getOrder(callback: Callback): void; 26 | public getOrder() { 27 | if (renege(this, this.getOrder, ...arguments)) return; 28 | return this.networkClient.get(...breakUrl(this.links.order.href)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/data/page/Page.ts: -------------------------------------------------------------------------------- 1 | import type Maybe from '../../types/Maybe'; 2 | import type Nullable from '../../types/Nullable'; 3 | import { type Links, type Url } from '../global'; 4 | 5 | export default interface Page extends Array { 6 | links: PageLinks; 7 | nextPageCursor: Maybe; 8 | previousPageCursor: Maybe; 9 | nextPage: Maybe<() => Promise>>; 10 | previousPage: Maybe<() => Promise>>; 11 | } 12 | 13 | export interface PageLinks extends Links { 14 | next: Nullable; 15 | previous: Nullable; 16 | } 17 | -------------------------------------------------------------------------------- /src/data/paymentLinks/PaymentLink.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Seal from '../../types/Seal'; 3 | import { type PaymentLinkData } from './data'; 4 | import PaymentLinkHelper from './PaymentLinkHelper'; 5 | 6 | type PaymentLink = Seal, PaymentLinkHelper>; 7 | 8 | export default PaymentLink; 9 | 10 | export function transform(networkClient: TransformingNetworkClient, input: PaymentLinkData): PaymentLink { 11 | return Object.assign(Object.create(new PaymentLinkHelper(networkClient, input._links)), input); 12 | } 13 | -------------------------------------------------------------------------------- /src/data/paymentLinks/PaymentLinkHelper.ts: -------------------------------------------------------------------------------- 1 | import { runIf } from 'ruply'; 2 | import breakUrl from '../../communication/breakUrl'; 3 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 4 | import emptyHelpfulIterator from '../../plumbing/iteration/emptyHelpfulIterator'; 5 | import type HelpfulIterator from '../../plumbing/iteration/HelpfulIterator'; 6 | import type { Payment } from '../../types'; 7 | import type { ThrottlingParameter } from '../../types/parameters'; 8 | import Helper from '../Helper'; 9 | import type { PaymentData } from '../payments/data'; 10 | import { type PaymentLinkData } from './data'; 11 | import type PaymentLink from './PaymentLink'; 12 | 13 | export default class PaymentLinkHelper extends Helper { 14 | constructor(networkClient: TransformingNetworkClient, protected readonly links: PaymentLinkData['_links']) { 15 | super(networkClient, links); 16 | } 17 | 18 | /** 19 | * Returns a direct link to the payment link. 20 | * 21 | * @since 3.6.0 22 | */ 23 | public getPaymentUrl(): string { 24 | return this.links.paymentLink.href; 25 | } 26 | 27 | /** 28 | * Retrieve the list of payments for a specific payment link. 29 | * 30 | * @since 4.3.0 31 | */ 32 | public getPayments(parameters?: ThrottlingParameter): HelpfulIterator { 33 | return ( 34 | runIf( 35 | /** 36 | * TODO: Should use this.links.payments but since the API doesn't support it yet, use the self-referencing link and add the payments path 37 | * For issue tracking see https://github.com/mollie/mollie-api-node/issues/417 38 | */ 39 | this.links.self, 40 | ({ href }) => breakUrl(href), 41 | ([pathname, query]) => this.networkClient.iterate(`${pathname}/payments`, 'payments', query, parameters?.valuesPerMinute), 42 | ) ?? emptyHelpfulIterator 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/data/payments/Payment.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Seal from '../../types/Seal'; 3 | import type Chargeback from '../chargebacks/Chargeback'; 4 | import { transform as transformChargeback } from '../chargebacks/Chargeback'; 5 | import type Refund from '../refunds/Refund'; 6 | import { transform as transformRefund } from '../refunds/Refund'; 7 | import type Capture from './captures/Capture'; 8 | import { transform as transformCapture } from './captures/Capture'; 9 | import { type PaymentData } from './data'; 10 | import PaymentHelper from './PaymentHelper'; 11 | 12 | type Payment = Seal< 13 | Omit & { 14 | _embedded?: { 15 | refunds?: Refund[]; 16 | chargebacks?: Chargeback[]; 17 | captures?: Capture[]; 18 | }; 19 | }, 20 | PaymentHelper 21 | >; 22 | 23 | export default Payment; 24 | 25 | export function transform(networkClient: TransformingNetworkClient, input: PaymentData): Payment { 26 | let _embedded: Payment['_embedded']; 27 | if (input._embedded != undefined) { 28 | _embedded = {}; 29 | if (input._embedded.chargebacks != undefined) { 30 | _embedded.chargebacks = input._embedded.chargebacks.map(transformChargeback.bind(undefined, networkClient)); 31 | } 32 | if (input._embedded.refunds != undefined) { 33 | _embedded.refunds = input._embedded.refunds.map(transformRefund.bind(undefined, networkClient)); 34 | } 35 | if (input._embedded.captures != undefined) { 36 | _embedded.captures = input._embedded.captures.map(transformCapture.bind(undefined, networkClient)); 37 | } 38 | } 39 | return Object.assign(Object.create(new PaymentHelper(networkClient, input._links, _embedded)), input, { _embedded }); 40 | } 41 | -------------------------------------------------------------------------------- /src/data/payments/captures/Capture.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../../communication/TransformingNetworkClient'; 2 | import type Seal from '../../../types/Seal'; 3 | import type Payment from '../Payment'; 4 | import { transform as transformPayment } from '../Payment'; 5 | import CaptureHelper from './CaptureHelper'; 6 | import { type CaptureData } from './data'; 7 | 8 | type Capture = Seal & { _embedded?: { payment?: Payment } }, CaptureHelper>; 9 | 10 | export default Capture; 11 | 12 | export function transform(networkClient: TransformingNetworkClient, input: CaptureData): Capture { 13 | let _embedded: Capture['_embedded']; 14 | if (input._embedded != undefined) { 15 | _embedded = {}; 16 | if (input._embedded.payment != undefined) { 17 | _embedded.payment = transformPayment(networkClient, input._embedded.payment); 18 | } 19 | } 20 | return Object.assign(Object.create(new CaptureHelper(networkClient, input._links, _embedded)), input, { _embedded }); 21 | } 22 | -------------------------------------------------------------------------------- /src/data/permissions/Permission.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Seal from '../../types/Seal'; 3 | import { type Links } from '../global'; 4 | import Helper from '../Helper'; 5 | import type Model from '../Model'; 6 | 7 | export interface PermissionData extends Model<'permission'> { 8 | /** 9 | * A short description of what the permission allows. 10 | * 11 | * @see https://docs.mollie.com/reference/v2/permissions-api/get-permission?path=description#response 12 | */ 13 | description: string; 14 | /** 15 | * Whether this permission is granted to the app by the organization or not. 16 | * 17 | * @see https://docs.mollie.com/reference/v2/permissions-api/get-permission?path=granted#response 18 | */ 19 | granted: boolean; 20 | /** 21 | * An object with several URL objects relevant to the permission. Every URL object will contain an `href` and a `type` field. 22 | * 23 | * @see https://docs.mollie.com/reference/v2/permissions-api/get-permission?path=_links#response 24 | */ 25 | _links: PermissionLinks; 26 | } 27 | 28 | type Permission = Seal>; 29 | 30 | export default Permission; 31 | 32 | export type PermissionLinks = Links; 33 | 34 | export function transform(networkClient: TransformingNetworkClient, input: PermissionData): Permission { 35 | return Object.assign(Object.create(new Helper(networkClient, input._links)), input); 36 | } 37 | -------------------------------------------------------------------------------- /src/data/profiles/Profile.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Seal from '../../types/Seal'; 3 | import { type ProfileData } from './data'; 4 | import ProfileHelper from './ProfileHelper'; 5 | 6 | type Profile = Seal; 7 | 8 | export default Profile; 9 | 10 | export function transform(networkClient: TransformingNetworkClient, input: ProfileData): Profile { 11 | return Object.assign(Object.create(new ProfileHelper(networkClient, input._links)), input); 12 | } 13 | -------------------------------------------------------------------------------- /src/data/refunds/Refund.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Seal from '../../types/Seal'; 3 | import type OrderLine from '../orders/orderlines/OrderLine'; 4 | import { transform as transformOrderLine } from '../orders/orderlines/OrderLine'; 5 | import type Payment from '../payments/Payment'; 6 | import { transform as transformPayment } from '../payments/Payment'; 7 | import { type RefundData } from './data'; 8 | import RefundHelper from './RefundHelper'; 9 | 10 | type Refund = Seal & { lines?: OrderLine[]; _embedded?: { payment?: Payment } }, RefundHelper>; 11 | 12 | export default Refund; 13 | 14 | export function transform(networkClient: TransformingNetworkClient, input: RefundData): Refund { 15 | let _embedded: Refund['_embedded']; 16 | if (input._embedded != undefined) { 17 | _embedded = {}; 18 | if (input._embedded.payment != undefined) { 19 | _embedded.payment = transformPayment(networkClient, input._embedded.payment); 20 | } 21 | } 22 | let lines: Refund['lines']; 23 | if (input.lines != undefined) { 24 | lines = input.lines.map(transformOrderLine); 25 | } 26 | return Object.assign(Object.create(new RefundHelper(networkClient, input._links, _embedded)), input, { 27 | lines, 28 | _embedded, 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /src/data/refunds/RefundHelper.ts: -------------------------------------------------------------------------------- 1 | import { runIf } from 'ruply'; 2 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 3 | import breakUrl from '../../communication/breakUrl'; 4 | import renege from '../../plumbing/renege'; 5 | import resolveIf from '../../plumbing/resolveIf'; 6 | import undefinedPromise from '../../plumbing/undefinedPromise'; 7 | import type Callback from '../../types/Callback'; 8 | import type Maybe from '../../types/Maybe'; 9 | import Helper from '../Helper'; 10 | import type Order from '../orders/Order'; 11 | import { type OrderData } from '../orders/data'; 12 | import type Payment from '../payments/Payment'; 13 | import { type PaymentData } from '../payments/data'; 14 | import type Refund from './Refund'; 15 | import { type RefundData } from './data'; 16 | 17 | export default class RefundHelper extends Helper { 18 | constructor( 19 | networkClient: TransformingNetworkClient, 20 | protected readonly links: RefundData['_links'], 21 | protected readonly embedded: RefundData['_embedded'], 22 | ) { 23 | super(networkClient, links); 24 | } 25 | 26 | /** 27 | * Returns the payment this refund was created for. 28 | * 29 | * @since 3.6.0 30 | */ 31 | public getPayment(): Promise; 32 | public getPayment(callback: Callback>): void; 33 | public getPayment() { 34 | if (renege(this, this.getPayment, ...arguments)) return; 35 | return resolveIf(this.embedded?.payment) ?? this.networkClient.get(...breakUrl(this.links.payment.href)); 36 | } 37 | 38 | /** 39 | * Returns the order this refund belongs to. 40 | * 41 | * @since 3.6.0 42 | */ 43 | public getOrder(): Promise | Promise; 44 | public getOrder(callback: Callback>): void; 45 | public getOrder() { 46 | if (renege(this, this.getOrder, ...arguments)) return; 47 | return ( 48 | runIf( 49 | this.links.order, 50 | ({ href }) => breakUrl(href), 51 | ([pathname, query]) => this.networkClient.get(pathname, query), 52 | ) ?? undefinedPromise 53 | ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/data/settlements/SettlementModel.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Seal from '../../types/Seal'; 3 | import { type SettlementData } from './data'; 4 | import SettlementHelper from './SettlementHelper'; 5 | 6 | type SettlementModel = Seal, SettlementHelper>; 7 | 8 | export default SettlementModel; 9 | 10 | export function transform(networkClient: TransformingNetworkClient, input: SettlementData): SettlementModel { 11 | return Object.assign(Object.create(new SettlementHelper(networkClient, input._links)), input); 12 | } 13 | -------------------------------------------------------------------------------- /src/data/subscriptions/Subscription.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Seal from '../../types/Seal'; 3 | import { type SubscriptionData } from './data'; 4 | import SubscriptionHelper from './SubscriptionHelper'; 5 | 6 | type Subscription = Seal; 7 | 8 | export default Subscription; 9 | 10 | export function transform(networkClient: TransformingNetworkClient, input: SubscriptionData): Subscription { 11 | return Object.assign(Object.create(new SubscriptionHelper(networkClient, input._links)), input); 12 | } 13 | -------------------------------------------------------------------------------- /src/data/terminals/Terminal.ts: -------------------------------------------------------------------------------- 1 | import type TransformingNetworkClient from '../../communication/TransformingNetworkClient'; 2 | import type Seal from '../../types/Seal'; 3 | import Helper from '../Helper'; 4 | import type { TerminalData } from './data'; 5 | 6 | type Terminal = Seal>; 7 | 8 | export default Terminal; 9 | 10 | export function transform(networkClient: TransformingNetworkClient, input: TerminalData): Terminal { 11 | return Object.assign(Object.create(new Helper(networkClient, input._links)), input); 12 | } 13 | -------------------------------------------------------------------------------- /src/data/terminals/data.ts: -------------------------------------------------------------------------------- 1 | import type Model from '../Model'; 2 | import { Links } from '../global'; 3 | 4 | export interface TerminalData extends Model<'terminal'> { 5 | /** 6 | * A short description of the terminal. The description can be used as an identifier for the terminal. Currently, the description is set when the terminal is initially configured. It will be visible in the Mollie Dashboard, and it may be visible on the device itself depending on the device. 7 | */ 8 | description: string; 9 | /** 10 | * The terminal's status. Refer to the documentation regarding statuses for more info about which statuses occur at what point. 11 | * 12 | * @see https://docs.mollie.com/reference/v2/terminals-api/get-terminal#response 13 | */ 14 | status: TerminalStatus; 15 | /** 16 | * The brand of the terminal. For example, ‘PAX’. 17 | */ 18 | brand?: string; 19 | /** 20 | * The model of the terminal. For example for a PAX A920, this field’s value will be ‘A920’. 21 | */ 22 | model?: string; 23 | /** 24 | * The serial number of the terminal. The serial number is provided at terminal creation time. 25 | */ 26 | serialNumber?: string; 27 | /** 28 | * The currency which is set for the terminal, in [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) format. Please take into consideration that currently our terminals are bound to a specific currency, chosen during setup. 29 | */ 30 | currency?: string; 31 | /** 32 | * The identifier used for referring to the profile the terminal was created on. For example, pfl_QkEhN94Ba. 33 | */ 34 | profileId?: string; 35 | /** 36 | * The date and time the terminal was created, in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. 37 | */ 38 | createdAt: string; 39 | _links: Links; 40 | } 41 | 42 | export enum TerminalStatus { 43 | /** 44 | * The device has been linked to your account, but has not yet been activated. If you ordered a terminal from us, it may already become visible in your account with this status. 45 | */ 46 | pending = 'pending', 47 | /** 48 | * The terminal is fully configured and ready to accept payments. 49 | */ 50 | active = 'active', 51 | /** 52 | * The terminal has been deactivated. Deactivation happens for example if you returned the device to Mollie, or if you requested to move it to another profile or organization. 53 | */ 54 | inactive = 'inactive', 55 | } 56 | -------------------------------------------------------------------------------- /src/plumbing/Throttler.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Six seconds, in milliseconds. 3 | */ 4 | const sixSeconds = 6e3; 5 | 6 | /** 7 | * Keeps track of the number of values which have been consumed, as well as the timeframe during which they were 8 | * consumed. The `throttle` method can be used to throttle if more values are consumed than allowed at any given moment 9 | * in time (overconsumption), as dictated by the `valuesPerMinute` argument passed into the constructor. 10 | */ 11 | export default class Throttler { 12 | protected count: number; 13 | protected readonly start: number; 14 | protected readonly valuesPerSixSeconds: number; 15 | constructor(valuesPerMinute: number) { 16 | this.valuesPerSixSeconds = valuesPerMinute / 10; 17 | this.start = Date.now(); 18 | this.count = 0; 19 | } 20 | 21 | /** 22 | * Registers that the passed number of values have been consumed. 23 | */ 24 | tally(count: number) { 25 | this.count += count; 26 | } 27 | 28 | /** 29 | * If more values have been consumed than allowed at this moment in time (overconsumption), a promise is returned 30 | * which is resolved as soon as this is no longer the case. Otherwise, `undefined` is returned. 31 | */ 32 | throttle() { 33 | const now = Date.now(); 34 | const timeOfNextValue = this.start + sixSeconds * Math.floor(this.count / this.valuesPerSixSeconds); 35 | if (now > timeOfNextValue) { 36 | return; 37 | } 38 | return new Promise(resolve => setTimeout(resolve, timeOfNextValue - now)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/plumbing/alias.ts: -------------------------------------------------------------------------------- 1 | import { apply, run } from 'ruply'; 2 | 3 | function createDescriptor(value: T) { 4 | return { 5 | configurable: true, 6 | /* enumerable: false, */ 7 | writable: true, 8 | value, 9 | } satisfies PropertyDescriptor; 10 | } 11 | 12 | /** 13 | * Defines new properties on the passed target object which take the value of the original property. The newly defined 14 | * properties are not enumerable and purposely do not exist in the TypeScript type of the target object. 15 | */ 16 | export default function alias(target: T, aliases: Record | string>) { 17 | Object.defineProperties( 18 | target, 19 | (Object.entries(aliases) as Array<[P, Array | string]>).reduce( 20 | (descriptors, [property, aliases]) => 21 | apply(descriptors, descriptors => { 22 | if (Array.isArray(aliases)) { 23 | aliases.forEach(alias => (descriptors[alias] = createDescriptor(target[property]))); 24 | } /* if ('string' == typeof aliases) */ else { 25 | descriptors[aliases as string] = createDescriptor(target[property]); 26 | } 27 | }), 28 | {} as PropertyDescriptorMap, 29 | ), 30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /src/plumbing/assertWellFormedId.ts: -------------------------------------------------------------------------------- 1 | import ApiError from '../errors/ApiError'; 2 | import type Maybe from '../types/Maybe'; 3 | 4 | const prefixes = { 5 | 'capture': 'cpt_', 6 | 'chargeback': 'chb_', 7 | 'customer': 'cst_', 8 | 'mandate': 'mdt_', 9 | 'order': 'ord_', 10 | 'orderline': 'odl_', 11 | 'organization': 'org_', 12 | 'payment': 'tr_', 13 | 'payment-link': 'pl_', 14 | 'profile': 'pfl_', 15 | 'refund': 're_', 16 | 'shipment': 'shp_', 17 | 'subscription': 'sub_', 18 | 'terminal': 'term_', 19 | } satisfies Record; 20 | 21 | type ResourceKind = keyof typeof prefixes; 22 | 23 | /** 24 | * Returns whether the passed identifier seems plausible (`true`); or is definitely invalid (`false`). 25 | */ 26 | function checkId(value: Maybe, resource: ResourceKind): value is string { 27 | if (typeof value != 'string') { 28 | return false; 29 | } 30 | return value.startsWith(prefixes[resource]); 31 | } 32 | 33 | /** 34 | * Asserts that the passed value is a well-formed identifier for the given resource as in 'this looks like it could be a valid identifier for this type of resource'. 35 | */ 36 | export default function assertWellFormedId(value: Maybe, resource: ResourceKind): asserts value is string { 37 | if (!checkId(value, resource)) { 38 | throw new ApiError(`The ${resource} id appears invalid: ${value} (unexpected format)`); 39 | } 40 | } -------------------------------------------------------------------------------- /src/plumbing/buildFromEntries.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns an object generated from the passed a list of key-value pairs. 3 | * 4 | * This function only exists to support Node.js < 12.0.0, which we only secretly support. Should we ever drop that 5 | * support completely, this function can be removed in favour of `Object.fromEntries`. 6 | */ 7 | export default ((): ((input: Iterable) => Record) => { 8 | if (Object.fromEntries != undefined) { 9 | return Object.fromEntries; 10 | } 11 | return function buildFromEntries(input: Iterable) { 12 | const result: Record = {}; 13 | Array.from(input, ([key, value]) => (result[key] = value)); 14 | return result; 15 | }; 16 | })(); 17 | -------------------------------------------------------------------------------- /src/plumbing/capitalize.ts: -------------------------------------------------------------------------------- 1 | const replaceArguments = [/(?:^|-+)(\w?)/g, (_: string, character: string) => character.toUpperCase()] as const; 2 | 3 | /** 4 | * Returns the passed input with all dashes (`'-'`) removed, and the first character as well as any character which 5 | * appears directly after a dash converted to upper case. `'bananas'` → `'Bananas'`. `'summer-day'` → `'SummerDay'`. 6 | */ 7 | export default function capitalize(input: string) { 8 | return input.replace(...replaceArguments); 9 | } 10 | -------------------------------------------------------------------------------- /src/plumbing/convertToNonNegativeInteger.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * `ToIntegerOrInfinity` (see https://tc39.es/ecma262/#sec-tointegerorinfinity) followed by a range check. 3 | * 4 | * In short: returns the passed input converted to an integer (rounded down) ‒ unless the passed input converts to 5 | * `NaN`, in which case `0` is returned; or the input is negative, in which case a `RangeError` is thrown. 6 | */ 7 | export default function convertToNonNegativeInteger(input: unknown) { 8 | const number = Number(input); 9 | if (number >= 0 == false) { 10 | if (isNaN(number)) { 11 | return 0; 12 | } /* if (number < 0) */ else { 13 | throw new RangeError(`Unexpected number ${input}`); 14 | } 15 | } 16 | return Math.floor(number); 17 | } 18 | -------------------------------------------------------------------------------- /src/plumbing/fling.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Like the `throw` keyword, but a function. 3 | */ 4 | export default function fling(error: Error): never; 5 | /** 6 | * Calls the passed error factory and throws the returned error. 7 | */ 8 | export default function fling(errorFactory: () => Error): never; 9 | export default function fling(errorOrFactory: Error | (() => Error)) { 10 | throw typeof errorOrFactory == 'function' ? errorOrFactory() : errorOrFactory; 11 | } 12 | -------------------------------------------------------------------------------- /src/plumbing/iteration/IteratorHelpers.ts: -------------------------------------------------------------------------------- 1 | import type Maybe from '../../types/Maybe'; 2 | 3 | type Vehicle = AsyncIterator | AsyncIterable; 4 | type MappedVehicle, U> = V extends AsyncIterator ? AsyncIterator : AsyncIterable; 5 | 6 | export default interface IteratorHelpers> { 7 | /** 8 | * Returns an iterator of the underlying sequence after skipping the passed limit. 9 | * 10 | * @since 3.6.0 11 | */ 12 | drop(limit: number): V & IteratorHelpers; 13 | 14 | /** 15 | * Returns whether every value in the sequence satisfies the passed callback. 16 | * 17 | * @since 3.6.0 18 | */ 19 | every(callback: (value: T) => boolean | Promise): Promise; 20 | 21 | /** 22 | * Returns an iterator of values in the sequence which satisfy the passed callback. 23 | * 24 | * @since 3.6.0 25 | */ 26 | filter(callback: (value: T) => boolean | Promise): V & IteratorHelpers; 27 | 28 | /** 29 | * Returns the first value in the sequence which satisfies the passed callback. 30 | */ 31 | find(callback: (value: T) => boolean | Promise): Promise>; 32 | 33 | /** 34 | * Calls the passed callback once for every value in the sequence. 35 | * 36 | * @since 3.6.0 37 | */ 38 | forEach(callback: (value: T) => any | Promise): Promise; 39 | 40 | /** 41 | * Returns an iterator of the values in the sequence with the passed callback applied. 42 | * 43 | * @since 3.6.0 44 | */ 45 | map(callback: (value: T) => U | Promise): MappedVehicle & IteratorHelpers>; 46 | 47 | /** 48 | * Returns whether at least one value in the sequence satisfies the passed callback. 49 | * 50 | * @since 3.6.0 51 | */ 52 | some(callback: (value: T) => boolean | Promise): Promise; 53 | 54 | /** 55 | * Returns an iterator of up to the passed limit of the values from the sequence. 56 | * 57 | * @since 3.6.0 58 | */ 59 | take(limit: number): V & IteratorHelpers; 60 | } 61 | -------------------------------------------------------------------------------- /src/plumbing/iteration/LazyIterator.ts: -------------------------------------------------------------------------------- 1 | import { apply } from 'ruply'; 2 | import type HelpfulIterator from './HelpfulIterator'; 3 | 4 | /** 5 | * An iterator which creates an upstream iterator using the factory function passed to the constructor, but only once 6 | * it is needed (when `next` is called, either directly or indirectly). 7 | */ 8 | export default class LazyIterator implements HelpfulIterator { 9 | /** 10 | * Returns the upstream iterator, creating said iterator if that had not happened yet (in other words: if this is the 11 | * first time this function is called). 12 | */ 13 | protected settle: () => HelpfulIterator; 14 | constructor(create: () => HelpfulIterator) { 15 | this.settle = () => 16 | apply( 17 | create(), 18 | // (The next time settle is called, return the just-created iterator.) 19 | iterator => (this.settle = () => iterator), 20 | ); 21 | } 22 | 23 | [Symbol.asyncIterator]() { 24 | return this; 25 | } 26 | 27 | next() { 28 | return this.settle().next(); 29 | } 30 | 31 | drop(limit: number) { 32 | return new LazyIterator(() => this.settle().drop(limit)); 33 | } 34 | 35 | every(callback: (value: T) => boolean | Promise) { 36 | return this.settle().every(callback); 37 | } 38 | 39 | filter(callback: (value: T) => boolean | Promise) { 40 | return new LazyIterator(() => this.settle().filter(callback)); 41 | } 42 | 43 | find(callback: (value: T) => boolean | Promise) { 44 | return this.settle().find(callback); 45 | } 46 | 47 | forEach(callback: (value: T) => any) { 48 | return this.settle().forEach(callback); 49 | } 50 | 51 | map(callback: (value: T) => U | Promise) { 52 | return new LazyIterator(() => this.settle().map(callback)); 53 | } 54 | 55 | some(callback: (value: T) => boolean | Promise) { 56 | return this.settle().some(callback); 57 | } 58 | 59 | take(limit: number): HelpfulIterator { 60 | return new LazyIterator(() => this.settle().take(limit)); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/plumbing/iteration/emptyHelpfulIterator.ts: -------------------------------------------------------------------------------- 1 | import HelpfulIterator from './HelpfulIterator'; 2 | import makeAsync from './makeAsync'; 3 | 4 | /** 5 | * A `HelpfulIterator` instance with an empty underlying sequence. 6 | */ 7 | export default new HelpfulIterator(makeAsync([][Symbol.iterator]())); 8 | -------------------------------------------------------------------------------- /src/plumbing/iteration/makeAsync.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Converts a (synchronous) iterator to an asynchronous iterator. 3 | */ 4 | export default function makeAsync(original: Iterator) { 5 | return { 6 | next() { 7 | return Promise.resolve(original.next()); 8 | }, 9 | 10 | return(value?: R) { 11 | return Promise.resolve(original.return?.(value) ?? { done: true, value: value as R }); 12 | }, 13 | 14 | throw(error: any) { 15 | return Promise.resolve(original.throw?.(error) ?? ({ done: true } as IteratorReturnResult)); 16 | }, 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /src/plumbing/renege.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Allows a promise-style method to be called callback-style. 3 | * 4 | * Behaves in one of two ways, depending on the type of the last argument: 5 | * * If called with a function as the last argument, that argument is considered to be the callback. This function 6 | * calls the passed method, forwarding the original arguments (save for the callback). A settlement of the promise 7 | * returned during that call will be forwarded to the callback. This function then returns `true`. 8 | * * If called with a last argument which is not a function, this function returns `false`. 9 | */ 10 | export default function renege(thisArgument: any, method: (...poppedArguments: any[]) => Promise, ...originalArguments: any[]): boolean { 11 | const candidate = originalArguments.pop(); 12 | if (typeof candidate == 'function') { 13 | method.apply(thisArgument, originalArguments).then((result: R) => void candidate(null, result), candidate); 14 | return true; 15 | } 16 | return false; 17 | } 18 | -------------------------------------------------------------------------------- /src/plumbing/resolveIf.ts: -------------------------------------------------------------------------------- 1 | import { runIf } from 'ruply'; 2 | 3 | type Nullish = null | undefined; 4 | 5 | /** 6 | * Returns a promise which resolves to the passed value; unless the passed value is 7 | * [nullish](https://developer.mozilla.org/docs/Glossary/Nullish), in which case it returns that value directly. 8 | */ 9 | export default function resolveIf(value: T extends Promise ? never : T) { 10 | return runIf(value, Promise.resolve.bind(Promise)) ?? (value as Extract | Promise>); 11 | } 12 | -------------------------------------------------------------------------------- /src/plumbing/undefinedPromise.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A promise which resolves to `undefined`. 3 | */ 4 | export default Promise.resolve(undefined); 5 | -------------------------------------------------------------------------------- /src/types/Callback.ts: -------------------------------------------------------------------------------- 1 | import type Nullable from './Nullable'; 2 | 3 | type Callback = (error: Nullable, result: R) => void; 4 | 5 | export default Callback; 6 | -------------------------------------------------------------------------------- /src/types/Maybe.ts: -------------------------------------------------------------------------------- 1 | type Maybe = T | undefined; 2 | 3 | export default Maybe; 4 | -------------------------------------------------------------------------------- /src/types/MaybeArray.ts: -------------------------------------------------------------------------------- 1 | type MaybeArray = T | T[]; 2 | 3 | export default MaybeArray; -------------------------------------------------------------------------------- /src/types/Nullable.ts: -------------------------------------------------------------------------------- 1 | type Nullable = T | null; 2 | 3 | export default Nullable; 4 | -------------------------------------------------------------------------------- /src/types/PickOptional.ts: -------------------------------------------------------------------------------- 1 | type PickOptional = { 2 | [P in K]?: T[P]; 3 | }; 4 | 5 | export default PickOptional; 6 | -------------------------------------------------------------------------------- /src/types/PickRequired.ts: -------------------------------------------------------------------------------- 1 | type PickRequired = { 2 | [P in K]-?: T[P]; 3 | }; 4 | 5 | export default PickRequired; 6 | -------------------------------------------------------------------------------- /src/types/Seal.ts: -------------------------------------------------------------------------------- 1 | type Seal = Readonly & H; 2 | 3 | export default Seal; 4 | -------------------------------------------------------------------------------- /src/types/Xor.ts: -------------------------------------------------------------------------------- 1 | type Xor = (B & { [P in keyof A]?: never }) | (A & { [P in keyof B]?: never }); 2 | 3 | export default Xor; 4 | -------------------------------------------------------------------------------- /src/types/parameters.ts: -------------------------------------------------------------------------------- 1 | export interface PaginationParameters { 2 | from?: string; 3 | limit?: number; 4 | } 5 | 6 | export interface ThrottlingParameter { 7 | /** 8 | * The number of values the iterator will produce per minute before throttling. Note that this value is not enforced 9 | * strictly; it is more of a hint. 10 | */ 11 | valuesPerMinute?: number; 12 | } 13 | 14 | export interface IdempotencyParameter { 15 | /** 16 | * The idempotency key sent to the Mollie API. The Mollie API uses this key to distinguish a single operation being 17 | * attempted twice from two separate similarly-looking operations. When provided, you can safety re-attempt an 18 | * operation without risk of said operation being performed twice. This is useful in case of network issues or your 19 | * server going down unexpectedly, as it is uncertain whether the operation was actually performed during the first 20 | * attempt in those situations. 21 | * 22 | * The Mollie API stores the response of every request made for a given idempotency key. A subsequent request with a 23 | * known key will cause the previously stored response to be replayed; instead of having the effect the request would 24 | * normally have. Note that the Mollie API will purge stored responses at some point. Re-attempts should happen 25 | * within an hour for this reason. 26 | * 27 | * If this property is `undefined`, a random idempotency key will be generated and used internally. This property 28 | * adds value only if the idempotency key is stored outside of the Mollie client. 29 | */ 30 | idempotencyKey?: string; 31 | } 32 | -------------------------------------------------------------------------------- /tests/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "import/no-unresolved": "off", 4 | "import/no-extraneous-dependencies": "off", 5 | "no-unused-vars": "off", 6 | "@typescript-eslint/no-var-requires": "off", 7 | "@typescript-eslint/no-unused-vars": "off", 8 | "@typescript-eslint/camelcase": "off", 9 | "@typescript-eslint/explicit-function-return-type": "off" 10 | }, 11 | "env": { 12 | "node": true, 13 | "jest": true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/getHead.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns whether the passed input is thenable (`true`) or not (`false`). 3 | */ 4 | function checkThenable(input: any): input is Promise { 5 | try { 6 | var { then } = input; 7 | } catch (error) { 8 | return false; 9 | } 10 | return 'function' == typeof then; 11 | } 12 | 13 | /** 14 | * Returns the first: 15 | * * element of the array to which the passed promise resolves, or 16 | * * value produced by the passed async iterator. 17 | */ 18 | export default function getHead(sequence: Promise> | AsyncIterator) { 19 | if (checkThenable(sequence)) { 20 | return sequence.then(array => { 21 | if (array.length == 0) { 22 | throw new Error('The array to which this promise resolved is empty'); 23 | } 24 | return array[0]; 25 | }); 26 | } /* if (checkThenable(sequence) == false) */ else { 27 | return sequence.next().then(({ done, value }) => { 28 | if (done) { 29 | throw new Error('The passed iterator produced no values'); 30 | } 31 | return value as T; 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/integration/chargebacks.test.ts: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv'; 2 | import createMollieClient from '../..'; 3 | 4 | /** 5 | * Load the API_KEY environment variable 6 | */ 7 | dotenv.config(); 8 | 9 | const mollieClient = createMollieClient({ apiKey: process.env.API_KEY }); 10 | 11 | describe('chargebacks', () => { 12 | it('should integrate', async () => { 13 | const chargebacks = await mollieClient.chargebacks.page(); 14 | 15 | expect(chargebacks).toBeDefined(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /tests/integration/customers.test.ts: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv'; 2 | import createMollieClient from '../..'; 3 | 4 | /** 5 | * Load the API_KEY environment variable 6 | */ 7 | dotenv.config(); 8 | 9 | const mollieClient = createMollieClient({ apiKey: process.env.API_KEY }); 10 | 11 | describe('customers', () => { 12 | it('should integrate', async () => { 13 | const customers = await mollieClient.customers.page(); 14 | 15 | expect(customers).toBeDefined(); 16 | 17 | const [mandates, payments, subscriptions] = await Promise.all([ 18 | mollieClient.customerMandates.page({ 19 | customerId: customers[0].id, 20 | }), 21 | mollieClient.customerPayments.page({ 22 | customerId: customers[0].id, 23 | }), 24 | mollieClient.customerSubscriptions.page({ 25 | customerId: customers[0].id, 26 | }), 27 | ]); 28 | 29 | expect(mandates).toBeDefined(); 30 | expect(payments).toBeDefined(); 31 | expect(subscriptions).toBeDefined(); 32 | 33 | if (mandates[0]) { 34 | const mandate = await mollieClient.customerMandates.get(mandates[0].id, { customerId: customers[0].id }); 35 | expect(mandate).toBeDefined(); 36 | } 37 | if (payments[0]) { 38 | const payment = await mollieClient.payments.get(payments[0].id); 39 | expect(payment).toBeDefined(); 40 | } 41 | if (subscriptions[0]) { 42 | try { 43 | const subscription = await mollieClient.customerSubscriptions.get(subscriptions[0].id, { customerId: customers[0].id }); 44 | expect(subscription).toBeDefined(); 45 | } catch (error) { 46 | expect(error).toEqual({ 47 | error: { 48 | message: 'The subscription has been cancelled', 49 | type: 'request', 50 | }, 51 | }); 52 | } 53 | } 54 | }); 55 | 56 | it('should refresh', async () => { 57 | // Create a customer. 58 | const originalCustomer = await mollieClient.customers.create({ 59 | email: 'john@example.org', 60 | name: 'John Doe', 61 | }); 62 | // Update the customer. 63 | await mollieClient.customers.update(originalCustomer.id, { name: 'Johnny Domen' }); 64 | // Get the updated customer. 65 | const updatedCustomer = await originalCustomer.refresh(); 66 | expect(originalCustomer.name).toBe('John Doe'); 67 | expect(updatedCustomer.name).toBe('Johnny Domen'); 68 | }); 69 | }); 70 | -------------------------------------------------------------------------------- /tests/integration/methods.test.ts: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv'; 2 | import createMollieClient from '../..'; 3 | 4 | /** 5 | * Load the API_KEY environment variable 6 | */ 7 | dotenv.config(); 8 | 9 | const mollieClient = createMollieClient({ apiKey: process.env.API_KEY }); 10 | 11 | describe('methods', () => { 12 | it('should integrate', async () => { 13 | const methods = await mollieClient.methods.list(); 14 | 15 | expect(methods).toBeDefined(); 16 | 17 | const method = await mollieClient.methods.get(methods[0].id); 18 | expect(method).toBeDefined(); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /tests/integration/refunds.test.ts: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv'; 2 | import createMollieClient from '../..'; 3 | 4 | /** 5 | * Load the API_KEY environment variable 6 | */ 7 | dotenv.config(); 8 | 9 | const mollieClient = createMollieClient({ apiKey: process.env.API_KEY }); 10 | 11 | describe('refunds', () => { 12 | it('should integrate', async () => { 13 | const refunds = await mollieClient.refunds.page(); 14 | 15 | expect(refunds).toBeDefined(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /tests/integration/terminals.test.ts: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv'; 2 | import createMollieClient from '../..'; 3 | 4 | /** 5 | * Load the API_KEY environment variable 6 | */ 7 | dotenv.config(); 8 | 9 | const mollieClient = createMollieClient({ apiKey: process.env.API_KEY }); 10 | 11 | describe('terminals', () => { 12 | // TODO: This test is skipped for now because it requires adding a terminal to the test account and thus potentially a dedicated API key. 13 | // https://github.com/mollie/mollie-api-node/pull/413?notification_referrer_id=NT_kwDOAC7wUbMxNTM1MTQzMjMwMDozMDc2MTc3#issuecomment-2765899992 14 | it.skip('should integrate', async () => { 15 | const terminals = await mollieClient.terminals.page(); 16 | 17 | expect(terminals).toBeDefined(); 18 | 19 | const terminal = await mollieClient.terminals.get(terminals[0].id); 20 | expect(terminal).toBeDefined(); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /tests/matchers/toBeDepleted.ts: -------------------------------------------------------------------------------- 1 | import { Interceptor } from 'nock'; 2 | 3 | declare global { 4 | namespace jest { 5 | interface Matchers { 6 | toBeDepleted(): Promise; 7 | } 8 | } 9 | } 10 | 11 | expect.extend({ 12 | toBeDepleted(received: Interceptor & { counter: number }) { 13 | const { isNot } = this; 14 | const pass = received.counter == 0; 15 | return { 16 | pass, 17 | message: () => 18 | 'expect(interceptor).toBeDepleted()' + // 19 | '\n\n' + 20 | `Expected an interceptor with count${isNot ? ' greater than' : ''}: 0\n` + 21 | `Received an interceptor with count: ${received.counter}`, 22 | }; 23 | }, 24 | }); 25 | -------------------------------------------------------------------------------- /tests/matchers/toStartWith.ts: -------------------------------------------------------------------------------- 1 | import 'jest'; 2 | 3 | declare global { 4 | namespace jest { 5 | interface Matchers { 6 | toStartWith(expected: string): CustomMatcherResult; 7 | } 8 | } 9 | } 10 | 11 | expect.extend({ 12 | toStartWith(received: string, expected: string) { 13 | const { isNot } = this; 14 | const pass = received.startsWith(expected); 15 | return { 16 | pass, 17 | message: () => 18 | 'expect(received).toStartWith(expected)' + // 19 | '\n\n' + 20 | `Expected a string which ${isNot ? 'does not start' : 'starts'} with: ${expected}\n` + 21 | `Received: ${received}`, 22 | }; 23 | }, 24 | }); 25 | -------------------------------------------------------------------------------- /tests/paymentLinks/paymentLinks.test.ts: -------------------------------------------------------------------------------- 1 | import { MollieClient } from '../..'; 2 | import getHead from '../getHead'; 3 | import NetworkMocker, { getAccessTokenClientProvider } from '../NetworkMocker'; 4 | 5 | // 'record' ‒ This test interacts with the real Mollie API over the network, and records the communication. 6 | // 'replay' ‒ This test uses existing recordings to simulate the network. 7 | const networkMode = 'replay'; 8 | 9 | describe('paymentLinks', () => { 10 | const networkMocker = new NetworkMocker.Auto(networkMode, getAccessTokenClientProvider, 'paymentLinks'); 11 | let mollieClient: MollieClient; 12 | 13 | beforeAll(async () => { 14 | mollieClient = await networkMocker.prepare(); 15 | }); 16 | 17 | test('paymentLinks', async () => { 18 | let paymentLink = await mollieClient.paymentLinks.create({ 19 | amount: { 20 | currency: 'EUR', 21 | value: '6.99', 22 | }, 23 | description: 'Hair pin', 24 | }); 25 | expect(paymentLink.getPaymentUrl()).toMatch(/^https:\/\/paymentlink\.mollie\.com\//); 26 | paymentLink = await mollieClient.paymentLinks.get(paymentLink.id); 27 | expect(paymentLink.amount?.value).toBe('6.99'); 28 | }); 29 | 30 | test('paymentLinks error response', async () => { 31 | await expect(mollieClient.paymentLinks.get('pl_fake_id')).rejects.toThrow('The resource with the token "pl_fake_id" could not be found.'); 32 | }); 33 | 34 | test('paymentLink payments', async () => { 35 | const paymentLink = await mollieClient.paymentLinks.get('pl_fake_with_payments'); 36 | 37 | const payments = paymentLink.getPayments(); 38 | 39 | const payment = await getHead(payments.take(1)); 40 | 41 | expect(payment.id).toBe('tr_5B8cwPMGnU6qLbRvo7qEZo'); 42 | }); 43 | 44 | afterAll(() => networkMocker.cleanup()); 45 | }); 46 | -------------------------------------------------------------------------------- /tests/profiles/profiles.test.ts: -------------------------------------------------------------------------------- 1 | import { ApiMode } from '../..'; 2 | import NetworkMocker, { getAccessTokenClientProvider } from '../NetworkMocker'; 3 | 4 | // 'record' ‒ This test interacts with the real Mollie API over the network, and records the communication. 5 | // 'replay' ‒ This test uses existing recordings to simulate the network. 6 | const networkMode = 'replay'; 7 | 8 | test('profiles', () => { 9 | return new NetworkMocker.Auto(networkMode, getAccessTokenClientProvider, 'profiles').use(async mollieClient => { 10 | // Create the profile. 11 | let profile = await mollieClient.profiles.create({ 12 | name: 'Iteration test profile', 13 | email: 'example@example.org', 14 | phone: '+31208202070', 15 | website: 'https://example.org', 16 | mode: ApiMode.test, 17 | }); 18 | // Update the profile. 19 | profile = await mollieClient.profiles.update(profile.id, { businessCategory: 'RESTAURANTS_NIGHTLIFE' }); 20 | expect(profile.businessCategory).toBe('RESTAURANTS_NIGHTLIFE'); 21 | // Enable and disable giftcard issuer. 22 | const giftcardIssuer = await mollieClient.profileGiftcardIssuers.enable({ profileId: profile.id, id: 'festivalcadeau' }); 23 | await mollieClient.profileGiftcardIssuers.disable({ profileId: profile.id, id: giftcardIssuer.id }); 24 | // Enable and disable voucher issuer. 25 | const voucherIssuer = await mollieClient.profileVoucherIssuers.enable({ profileId: profile.id, id: 'appetiz', contractId: 'test_contract_id' }); 26 | await mollieClient.profileVoucherIssuers.disable({ profileId: profile.id, id: voucherIssuer.id }); 27 | // Delete the profile. 28 | expect(await mollieClient.profiles.delete(profile.id)).toBe(true); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /tests/tick.ts: -------------------------------------------------------------------------------- 1 | import { run } from 'ruply'; 2 | 3 | /** 4 | * Attempts to clear the microtask queue. 5 | */ 6 | export default run(setTimeout, setTimeout => async (count = 6) => { 7 | while (count-- != 0) { 8 | await new Promise(resolve => setTimeout(resolve)); 9 | } 10 | }); 11 | -------------------------------------------------------------------------------- /tests/unit/__stubs__/list/customers_page_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 2, 3 | "_embedded": { 4 | "customers": [ 5 | { 6 | "resource": "customer", 7 | "id": "cst_1DVwgVBLS", 8 | "mode": "test", 9 | "name": "Customer 7", 10 | "email": "customer7@example.org", 11 | "locale": "nl_NL", 12 | "metadata": null, 13 | "createdAt": "2018-04-06T13:23:21.0Z", 14 | "_links": { 15 | "self": { 16 | "href": "https://api.mollie.com/v2/customers/cst_1DVwgVBLS", 17 | "type": "application/hal+json" 18 | }, 19 | "documentation": { 20 | "href": "https://docs.mollie.com/reference/v2/customers-api/get-customer", 21 | "type": "text/html" 22 | } 23 | } 24 | }, 25 | { 26 | "resource": "customer", 27 | "id": "cst_r1EOkmyO6", 28 | "mode": "test", 29 | "name": "Customer 8", 30 | "email": "customer8@example.org", 31 | "locale": "nl_NL", 32 | "metadata": null, 33 | "createdAt": "2018-04-06T13:23:21.0Z", 34 | "_links": { 35 | "self": { 36 | "href": "https://api.mollie.com/v2/customers/cst_r1EOkmyO6", 37 | "type": "application/hal+json" 38 | }, 39 | "documentation": { 40 | "href": "https://docs.mollie.com/reference/v2/customers-api/get-customer", 41 | "type": "text/html" 42 | } 43 | } 44 | } 45 | ] 46 | }, 47 | "_links": { 48 | "self": { 49 | "href": "https://api.mollie.com/v2/customers", 50 | "type": "application/hal+json" 51 | }, 52 | "previous": { 53 | "href": "https://api.mollie.com/v2/customers?from=cst_l4J9zsdzO&limit=3", 54 | "type": "application/hal+json" 55 | }, 56 | "next": null, 57 | "documentation": { 58 | "href": "https://docs.mollie.com/reference/v2/customers-api/list-customers", 59 | "type": "text/html" 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tests/unit/backwards-compatibitily.test.ts: -------------------------------------------------------------------------------- 1 | import createMollieClient from '../..'; 2 | 3 | test('client object should have aliases for backwards-compatibility', () => { 4 | const client = createMollieClient({ apiKey: 'mock-api-key' }); 5 | // eslint-disable-next-line @typescript-eslint/ban-ts-ignore 6 | // @ts-ignore 7 | expect(client.payments_refunds).toBe(client.paymentRefunds); 8 | // eslint-disable-next-line @typescript-eslint/ban-ts-ignore 9 | // @ts-ignore 10 | expect(client.customers_subscriptions).toBe(client.customerSubscriptions); 11 | }); 12 | 13 | test('binder should have aliases for backwards-compatibility', () => { 14 | const client = createMollieClient({ apiKey: 'mock-api-key' }); 15 | // eslint-disable-next-line @typescript-eslint/ban-ts-ignore 16 | // @ts-ignore 17 | expect(client.paymentRefunds.all).toBe(client.paymentRefunds.page); 18 | // eslint-disable-next-line @typescript-eslint/ban-ts-ignore 19 | // @ts-ignore 20 | expect(client.paymentRefunds.list).toBe(client.paymentRefunds.page); 21 | }); 22 | -------------------------------------------------------------------------------- /tests/unit/createMollieClient.test.ts: -------------------------------------------------------------------------------- 1 | import createMollieClient from '../..'; 2 | 3 | describe('createMollieClient', () => { 4 | it('should fail when no credentials are provided', () => { 5 | // eslint-disable-next-line @typescript-eslint/ban-ts-ignore 6 | // @ts-ignore 7 | expect(() => createMollieClient({})).toThrow('Missing parameter "apiKey" or "accessToken".'); 8 | }); 9 | 10 | it('should throw a descriptive error when a apiKey is set to null', () => { 11 | // eslint-disable-next-line @typescript-eslint/ban-ts-ignore 12 | // @ts-ignore 13 | expect(() => createMollieClient({ apiKey: null })).toThrow('Parameter "apiKey" is null.'); 14 | }); 15 | 16 | it('should throw a descriptive error when a apiKey is set to an empty string', () => { 17 | expect(() => createMollieClient({ apiKey: '' })).toThrow('Parameter "apiKey" is an empty string.'); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /tests/unit/inspect.test.ts: -------------------------------------------------------------------------------- 1 | import { inspect } from 'util'; 2 | import '../matchers/toStartWith'; 3 | import NetworkMocker, { getApiKeyClientProvider } from '../NetworkMocker'; 4 | 5 | test('inspect', () => { 6 | return new NetworkMocker(getApiKeyClientProvider()).use(async ([mollieClient, networkMocker]) => { 7 | networkMocker 8 | .intercept('GET', '/methods/ideal', 200, { 9 | resource: 'method', 10 | id: 'ideal', 11 | description: 'iDEAL', 12 | minimumAmount: { 13 | value: '0.01', 14 | currency: 'EUR', 15 | }, 16 | maximumAmount: { 17 | value: '50000.00', 18 | currency: 'EUR', 19 | }, 20 | image: { 21 | size1x: 'https://www.mollie.com/external/icons/payment-methods/ideal.png', 22 | size2x: 'https://www.mollie.com/external/icons/payment-methods/ideal%402x.png', 23 | svg: 'https://www.mollie.com/external/icons/payment-methods/ideal.svg', 24 | }, 25 | status: 'activated', 26 | pricing: [ 27 | { 28 | description: 'Netherlands', 29 | fixed: { 30 | value: '0.29', 31 | currency: 'EUR', 32 | }, 33 | variable: '0', 34 | }, 35 | ], 36 | _links: { 37 | self: { 38 | href: 'https://api.mollie.com/v2/methods/ideal?include=pricing', 39 | type: 'application/hal+json', 40 | }, 41 | documentation: { 42 | href: 'https://docs.mollie.com/reference/v2/methods-api/get-method', 43 | type: 'text/html', 44 | }, 45 | }, 46 | }) 47 | .twice(); 48 | 49 | const method = await mollieClient.methods.get('ideal'); 50 | 51 | expect(inspect(method)).toStartWith('Method ideal {'); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /tests/unit/models/onboarding.test.ts: -------------------------------------------------------------------------------- 1 | import { Onboarding } from '../../..'; 2 | import NetworkMocker, { getApiKeyClientProvider } from '../../NetworkMocker'; 3 | 4 | function getOnboarding(status) { 5 | return new NetworkMocker(getApiKeyClientProvider()).use(([mollieClient, networkMocker]) => { 6 | networkMocker.intercept('GET', '/onboarding/me', 200, { 7 | resource: 'onboarding', 8 | name: 'Mollie B.V.', 9 | signedUpAt: '2018-12-20T10:49:08+00:00', 10 | status, 11 | canReceivePayments: true, 12 | canReceiveSettlements: true, 13 | _links: { 14 | self: { 15 | href: 'https://api.mollie.com/v2/onboarding/me', 16 | type: 'application/hal+json', 17 | }, 18 | onboarding: { 19 | href: 'https://www.mollie.com/dashboard/onboarding', 20 | type: 'text/html', 21 | }, 22 | organization: { 23 | href: 'https://api.mollie.com/v2/organization/org_12345', 24 | type: 'application/hal+json', 25 | }, 26 | documentation: { 27 | href: 'https://docs.mollie.com/reference/v2/onboarding-api/get-onboarding-status', 28 | type: 'text/html', 29 | }, 30 | }, 31 | }).twice(); 32 | 33 | return bluster(mollieClient.onboarding.get.bind(mollieClient.onboarding))(); 34 | }); 35 | } 36 | 37 | test('onboardingStatuses', () => { 38 | return Promise.all( 39 | ['needs-data', 'in-review', 'completed'].map(async status => { 40 | const onboarding = await getOnboarding(status); 41 | 42 | expect(onboarding.status).toBe(status); 43 | }), 44 | ); 45 | }); 46 | -------------------------------------------------------------------------------- /tests/unit/models/profile.test.ts: -------------------------------------------------------------------------------- 1 | import { Profile } from '../../..'; 2 | import NetworkMocker, { getApiKeyClientProvider } from '../../NetworkMocker'; 3 | 4 | function getProfile(status) { 5 | return new NetworkMocker(getApiKeyClientProvider()).use(([mollieClient, networkMocker]) => { 6 | networkMocker.intercept('GET', '/profiles/pfl_ahe8z8OPut', 200, { 7 | resource: 'profile', 8 | id: 'pfl_ahe8z8OPut', 9 | mode: 'live', 10 | name: 'My website name', 11 | website: 'http://www.mywebsite.com', 12 | email: 'info@mywebsite.com', 13 | phone: '31123456789', 14 | categoryCode: 5399, 15 | status, 16 | review: { 17 | status: 'pending', 18 | }, 19 | createdAt: '2016-01-11T13:03:55+00:00', 20 | _links: { 21 | self: { 22 | href: 'https://api.mollie.com/v2/profiles/pfl_ahe8z8OPut', 23 | type: 'application/hal+json', 24 | }, 25 | chargebacks: { 26 | href: 'https://api.mollie.com/v2/chargebacks?profileId=pfl_ahe8z8OPut', 27 | type: 'application/hal+json', 28 | }, 29 | methods: { 30 | href: 'https://api.mollie.com/v2/methods?profileId=pfl_ahe8z8OPut', 31 | type: 'application/hal+json', 32 | }, 33 | payments: { 34 | href: 'https://api.mollie.com/v2/payments?profileId=pfl_ahe8z8OPut', 35 | type: 'application/hal+json', 36 | }, 37 | refunds: { 38 | href: 'https://api.mollie.com/v2/refunds?profileId=pfl_ahe8z8OPut', 39 | type: 'application/hal+json', 40 | }, 41 | checkoutPreviewUrl: { 42 | href: 'https://www.mollie.com/payscreen/preview/pfl_ahe8z8OPut', 43 | type: 'text/html', 44 | }, 45 | }, 46 | }).twice(); 47 | 48 | return bluster(mollieClient.profiles.get.bind(mollieClient.profiles))('pfl_ahe8z8OPut'); 49 | }); 50 | } 51 | 52 | test('profileStatuses', () => { 53 | return Promise.all( 54 | ['blocked', 'verified', 'unverified'].map(async status => { 55 | const profile = await getProfile(status); 56 | 57 | expect(profile.status).toBe(status); 58 | }), 59 | ); 60 | }); 61 | -------------------------------------------------------------------------------- /tests/unit/models/refund.test.ts: -------------------------------------------------------------------------------- 1 | import { Refund } from '../../..'; 2 | import NetworkMocker, { getApiKeyClientProvider } from '../../NetworkMocker'; 3 | 4 | function getRefund(status) { 5 | return new NetworkMocker(getApiKeyClientProvider()).use(([mollieClient, networkMocker]) => { 6 | networkMocker.intercept('GET', '/refunds', 200, { 7 | _embedded: { 8 | refunds: [ 9 | { 10 | resource: 'refund', 11 | id: 're_haCsig5aru', 12 | amount: { 13 | value: '2.00', 14 | currency: 'EUR', 15 | }, 16 | status, 17 | createdAt: '2018-03-28T10:56:10+00:00', 18 | description: 'My first API payment', 19 | paymentId: 'tr_44aKxzEbr8', 20 | settlementAmount: { 21 | value: '-2.00', 22 | currency: 'EUR', 23 | }, 24 | _links: { 25 | self: { 26 | href: 'https://api.mollie.com/v2/payments/tr_44aKxzEbr8/refunds/re_haCsig5aru', 27 | type: 'application/hal+json', 28 | }, 29 | payment: { 30 | href: 'https://api.mollie.com/v2/payments/tr_44aKxzEbr8', 31 | type: 'application/hal+json', 32 | }, 33 | }, 34 | }, 35 | ], 36 | }, 37 | _links: { 38 | documentation: { 39 | href: 'https://docs.mollie.com/reference/v2/refunds-api/list-refunds', 40 | type: 'text/html', 41 | }, 42 | self: { 43 | href: 'http://api.mollie.nl/v2/refunds?limit=10', 44 | type: 'application/hal+json', 45 | }, 46 | previous: null, 47 | next: null, 48 | }, 49 | count: 1, 50 | }).twice(); 51 | 52 | return bluster(mollieClient.refunds.page.bind(mollieClient.refunds))().then(refunds => refunds[0]); 53 | }); 54 | } 55 | 56 | test('refundStatuses', () => { 57 | return Promise.all( 58 | ['pending', 'processing', 'queued', 'refunded'].map(async status => { 59 | const refund = await getRefund(status); 60 | 61 | expect(refund.status).toBe(status); 62 | }), 63 | ); 64 | }); 65 | -------------------------------------------------------------------------------- /tests/unit/models/subscription.test.ts: -------------------------------------------------------------------------------- 1 | import { Subscription } from '../../..'; 2 | import NetworkMocker, { getApiKeyClientProvider } from '../../NetworkMocker'; 3 | 4 | function getSubscription(status) { 5 | return new NetworkMocker(getApiKeyClientProvider()).use(([mollieClient, networkMocker]) => { 6 | networkMocker.intercept('GET', '/customers/cst_FhQJRw4s2n/subscriptions/sub_wByQa6efm6', 200, { 7 | resource: 'subscription', 8 | id: 'sub_wByQa6efm6', 9 | mode: 'test', 10 | createdAt: '2018-04-24T11:41:55+00:00', 11 | status, 12 | amount: { 13 | value: '10.00', 14 | currency: 'EUR', 15 | }, 16 | description: 'Order 1234', 17 | method: null, 18 | times: null, 19 | interval: '1 month', 20 | startDate: '2018-04-24', 21 | webhookUrl: null, 22 | _links: { 23 | self: { 24 | href: 'https://api.mollie.com/v2/customers/cst_FhQJRw4s2n/subscriptions/sub_wByQa6efm6', 25 | type: 'application/hal+json', 26 | }, 27 | customer: { 28 | href: 'https://api.mollie.com/v2/customers/cst_FhQJRw4s2n', 29 | type: 'application/hal+json', 30 | }, 31 | documentation: { 32 | href: 'https://docs.mollie.com/reference/v2/subscriptions-api/create-subscription', 33 | type: 'text/html', 34 | }, 35 | }, 36 | }).twice(); 37 | 38 | return bluster(mollieClient.customerSubscriptions.get.bind(mollieClient.customerSubscriptions))('sub_wByQa6efm6', { customerId: 'cst_FhQJRw4s2n' }); 39 | }); 40 | } 41 | 42 | test('subscriptionStatuses', () => { 43 | return Promise.all( 44 | ['pending', 'canceled', 'completed', 'suspended', 'active'].map(async status => { 45 | const subscription = await getSubscription(status); 46 | 47 | expect(subscription.status).toBe(status); 48 | }), 49 | ); 50 | }); 51 | -------------------------------------------------------------------------------- /tests/unit/resources/__snapshots__/lists.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`lists .list() should retrieve the next page 1`] = ` 4 | [ 5 | { 6 | "_links": { 7 | "documentation": { 8 | "href": "https://docs.mollie.com/reference/v2/customers-api/get-customer", 9 | "type": "text/html", 10 | }, 11 | "self": { 12 | "href": "https://api.mollie.com/v2/customers/cst_l4J9zsdzO", 13 | "type": "application/hal+json", 14 | }, 15 | }, 16 | "createdAt": "2018-04-06T13:23:21.0Z", 17 | "email": "customer4@example.org", 18 | "id": "cst_l4J9zsdzO", 19 | "locale": "nl_NL", 20 | "metadata": null, 21 | "mode": "test", 22 | "name": "Customer 4", 23 | "resource": "customer", 24 | }, 25 | { 26 | "_links": { 27 | "documentation": { 28 | "href": "https://docs.mollie.com/reference/v2/customers-api/get-customer", 29 | "type": "text/html", 30 | }, 31 | "self": { 32 | "href": "https://api.mollie.com/v2/customers/cst_CFAhWkIKz", 33 | "type": "application/hal+json", 34 | }, 35 | }, 36 | "createdAt": "2018-04-06T13:23:21.0Z", 37 | "email": "customer5@example.org", 38 | "id": "cst_CFAhWkIKz", 39 | "locale": "nl_NL", 40 | "metadata": null, 41 | "mode": "test", 42 | "name": "Customer 5", 43 | "resource": "customer", 44 | }, 45 | { 46 | "_links": { 47 | "documentation": { 48 | "href": "https://docs.mollie.com/reference/v2/customers-api/get-customer", 49 | "type": "text/html", 50 | }, 51 | "self": { 52 | "href": "https://api.mollie.com/v2/customers/cst_5BsP6Y1S8", 53 | "type": "application/hal+json", 54 | }, 55 | }, 56 | "createdAt": "2018-04-06T13:23:21.0Z", 57 | "email": "customer6@example.org", 58 | "id": "cst_5BsP6Y1S8", 59 | "locale": "nl_NL", 60 | "metadata": null, 61 | "mode": "test", 62 | "name": "Customer 6", 63 | "resource": "customer", 64 | }, 65 | ] 66 | `; 67 | -------------------------------------------------------------------------------- /tests/unit/resources/applePay.test.ts: -------------------------------------------------------------------------------- 1 | import NetworkMocker, { getApiKeyClientProvider } from '../../NetworkMocker'; 2 | 3 | test('requestApplePayPaymentSession', () => { 4 | return new NetworkMocker(getApiKeyClientProvider()).use(async ([mollieClient, networkMocker]) => { 5 | networkMocker.intercept('POST', '/wallets/applepay/sessions', 201, { 6 | epochTimestamp: 1555507053169, 7 | expiresAt: 1555510653169, 8 | merchantSessionIdentifier: 'SSH2EAF8AFAEAA94DEEA898162A5DAFD36E_916523AAED1343F5BC5815E12BEE9250AFFDC1A17C46B0DE5A943F0F94927C24', 9 | nonce: '0206b8db', 10 | merchantIdentifier: 'BD62FEB196874511C22DB28A9E14A89E3534C93194F73EA417EC566368D391EB', 11 | domainName: 'pay.example.org', 12 | displayName: "Chuck Norris's Store", 13 | signature: '308006092a864886f7...8cc030ad3000000000000', 14 | }).twice(); 15 | 16 | const applePaySession = await bluster(mollieClient.applePay.requestPaymentSession.bind(mollieClient.applePay))({ 17 | domain: 'pay.mywebshop.com', 18 | validationUrl: 'https://apple-pay-gateway-cert.apple.com/paymentservices/paymentSession', 19 | }); 20 | 21 | expect(applePaySession.epochTimestamp).toBe(1555507053169); 22 | expect(applePaySession.expiresAt).toBe(1555510653169); 23 | expect(applePaySession.merchantSessionIdentifier).toBe('SSH2EAF8AFAEAA94DEEA898162A5DAFD36E_916523AAED1343F5BC5815E12BEE9250AFFDC1A17C46B0DE5A943F0F94927C24'); 24 | expect(applePaySession.nonce).toBe('0206b8db'); 25 | expect(applePaySession.merchantIdentifier).toBe('BD62FEB196874511C22DB28A9E14A89E3534C93194F73EA417EC566368D391EB'); 26 | expect(applePaySession.domainName).toBe('pay.example.org'); 27 | expect(applePaySession.displayName).toBe("Chuck Norris's Store"); 28 | expect(applePaySession.signature).toBe('308006092a864886f7...8cc030ad3000000000000'); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /tests/unit/resources/lists.test.ts: -------------------------------------------------------------------------------- 1 | import CustomersBinder from '../../../src/binders/customers/CustomersBinder'; 2 | import NetworkClient from '../../../src/communication/NetworkClient'; 3 | 4 | import NetworkMocker, { getApiKeyClientProvider } from '../../NetworkMocker'; 5 | import page1 from '../__stubs__/list/customers_page_1.json'; 6 | import page2 from '../__stubs__/list/customers_page_2.json'; 7 | 8 | describe('lists', () => { 9 | let customers: CustomersBinder; 10 | beforeEach(() => { 11 | customers = new CustomersBinder(new NetworkClient({ apiKey: 'mock-api-key', nodeVersion: process.version, libraryVersion: 'mock' })); 12 | }); 13 | 14 | describe('.list()', () => { 15 | it('should retrieve a limited list', () => { 16 | return new NetworkMocker(getApiKeyClientProvider()).use(async ([, networkMocker]) => { 17 | networkMocker.intercept('GET', '/customers?limit=3', 200, page1); 18 | const result = await customers.page({ limit: 3 }); 19 | expect(result).toHaveLength(3); 20 | expect(result[2].resource).toEqual('customer'); 21 | }); 22 | }); 23 | 24 | it('should retrieve the next page', () => { 25 | return new NetworkMocker(getApiKeyClientProvider()).use(async ([, networkMocker]) => { 26 | networkMocker.intercept('GET', '/customers?limit=3', 200, page1); 27 | networkMocker.intercept('GET', '/customers?limit=3&from=cst_l4J9zsdzO', 200, page2); 28 | const list1 = await customers.page({ limit: 3 }); 29 | const list2 = await list1.nextPage?.(); 30 | expect(list2).toHaveLength(3); 31 | expect(list2![0].id).toEqual('cst_l4J9zsdzO'); 32 | expect(list2?.nextPageCursor).toEqual('cst_1DVwgVBLS'); 33 | expect(list2).toMatchSnapshot(); 34 | }); 35 | }); 36 | 37 | it('should retrieve page with a callback', done => { 38 | new NetworkMocker(getApiKeyClientProvider()).use(async ([, networkMocker]) => { 39 | networkMocker.intercept('GET', '/customers?limit=3', 200, page1); 40 | customers.page({ limit: 3 }, (err, result): void => { 41 | expect(err).toBeNull(); 42 | expect(result[0].id).toEqual('cst_kEn1PlbGa'); 43 | expect(result.nextPageCursor).toEqual('cst_l4J9zsdzO'); 44 | expect(result.nextPage).toBeDefined(); 45 | done(); 46 | }); 47 | }); 48 | }); 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /tests/unit/resources/subscriptions.test.ts: -------------------------------------------------------------------------------- 1 | import NetworkMocker, { getApiKeyClientProvider } from '../../NetworkMocker'; 2 | 3 | test('listPageOfRootSubscriptions', () => { 4 | return new NetworkMocker(getApiKeyClientProvider()).use(async ([mollieClient, networkMocker]) => { 5 | networkMocker.intercept('GET', '/subscriptions', 200, { 6 | _embedded: { 7 | subscriptions: [ 8 | { 9 | resource: 'subscription', 10 | id: 'sub_wByQa6efm6', 11 | mode: 'test', 12 | createdAt: '2018-04-24T11:41:55+00:00', 13 | status: 'active', 14 | amount: { 15 | value: '10.00', 16 | currency: 'EUR', 17 | }, 18 | description: 'Order 1234', 19 | method: null, 20 | times: null, 21 | interval: '1 month', 22 | startDate: '2018-04-24', 23 | webhookUrl: null, 24 | _links: { 25 | self: { 26 | href: 'https://api.mollie.com/v2/customers/cst_FhQJRw4s2n/subscriptions/sub_wByQa6efm6', 27 | type: 'application/hal+json', 28 | }, 29 | customer: { 30 | href: 'https://api.mollie.com/v2/customers/cst_FhQJRw4s2n', 31 | type: 'application/hal+json', 32 | }, 33 | }, 34 | }, 35 | ], 36 | }, 37 | count: 1, 38 | _links: { 39 | documentation: { 40 | href: 'https://docs.mollie.com/reference/v2/subscriptions-api/list-subscriptions', 41 | type: 'text/html', 42 | }, 43 | self: { 44 | href: 'https://api.mollie.com/v2/subscriptions?limit=50', 45 | type: 'application/hal+json', 46 | }, 47 | previous: null, 48 | next: null, 49 | }, 50 | }).twice(); 51 | 52 | const subscriptions = await bluster(mollieClient.subscription.page.bind(mollieClient.subscription))(); 53 | 54 | expect(subscriptions.length).toBe(1); 55 | 56 | expect(subscriptions[0].resource).toBe('subscription'); 57 | expect(subscriptions[0].id).toBe('sub_wByQa6efm6'); 58 | // No need to test all attributes here ... 59 | }); 60 | }); 61 | -------------------------------------------------------------------------------- /tsconfig-declarations.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "files": ["src/types.ts", "src/certs.d.ts"], 4 | "compilerOptions": { 5 | "emitDeclarationOnly": true, 6 | "declaration": true, 7 | "declarationDir": "dist/types" 8 | } 9 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "resolveJsonModule": true, 4 | "esModuleInterop": true, 5 | "target": "esnext", 6 | "moduleResolution": "node", 7 | "strict": true 8 | } 9 | } --------------------------------------------------------------------------------