From 0876f2b542c36e28ce487caf5337180bba37a8ab Mon Sep 17 00:00:00 2001 From: Justin Case Date: Sun, 6 Oct 2024 17:36:35 +0200 Subject: [PATCH] Add Payment Links API Closes GH-174 --- examples/payment-links/create.rb | 5 + examples/payment-links/delete.rb | 1 + examples/payment-links/get.rb | 1 + examples/payment-links/list-payments.rb | 2 + examples/payment-links/list.rb | 1 + examples/payment-links/update.rb | 5 + lib/mollie.rb | 1 + lib/mollie/base.rb | 2 + lib/mollie/list.rb | 2 +- lib/mollie/payment_link.rb | 70 ++++++++++++ test/fixtures/payment_links/create.json | 7 ++ test/fixtures/payment_links/get.json | 32 ++++++ .../fixtures/payment_links/list-payments.json | 31 ++++++ test/fixtures/payment_links/list.json | 31 ++++++ test/fixtures/payment_links/update.json | 4 + test/mollie/payment_link_test.rb | 100 ++++++++++++++++++ 16 files changed, 294 insertions(+), 1 deletion(-) create mode 100644 examples/payment-links/create.rb create mode 100644 examples/payment-links/delete.rb create mode 100644 examples/payment-links/get.rb create mode 100644 examples/payment-links/list-payments.rb create mode 100644 examples/payment-links/list.rb create mode 100644 examples/payment-links/update.rb create mode 100644 lib/mollie/payment_link.rb create mode 100644 test/fixtures/payment_links/create.json create mode 100644 test/fixtures/payment_links/get.json create mode 100644 test/fixtures/payment_links/list-payments.json create mode 100644 test/fixtures/payment_links/list.json create mode 100644 test/fixtures/payment_links/update.json create mode 100644 test/mollie/payment_link_test.rb diff --git a/examples/payment-links/create.rb b/examples/payment-links/create.rb new file mode 100644 index 0000000..d490e32 --- /dev/null +++ b/examples/payment-links/create.rb @@ -0,0 +1,5 @@ +payment_link = Mollie::PaymentLink.create( + description: "Bicycle tires", + amount: { currency: "EUR", value: "24.95" } +) + diff --git a/examples/payment-links/delete.rb b/examples/payment-links/delete.rb new file mode 100644 index 0000000..c603be9 --- /dev/null +++ b/examples/payment-links/delete.rb @@ -0,0 +1 @@ +Mollie::PaymentLink.delete("pl_4Y0eZitmBnQ6IDoMqZQKh") diff --git a/examples/payment-links/get.rb b/examples/payment-links/get.rb new file mode 100644 index 0000000..6486584 --- /dev/null +++ b/examples/payment-links/get.rb @@ -0,0 +1 @@ +payment_link = Mollie::PaymentLink.get("pl_4Y0eZitmBnQ6IDoMqZQKh") diff --git a/examples/payment-links/list-payments.rb b/examples/payment-links/list-payments.rb new file mode 100644 index 0000000..1db5c06 --- /dev/null +++ b/examples/payment-links/list-payments.rb @@ -0,0 +1,2 @@ +payment_link = Mollie::PaymentLink.get("pl_4Y0eZitmBnQ6IDoMqZQKh") +payments = payment_link.payments diff --git a/examples/payment-links/list.rb b/examples/payment-links/list.rb new file mode 100644 index 0000000..e4e8d66 --- /dev/null +++ b/examples/payment-links/list.rb @@ -0,0 +1 @@ +payment_links = Mollie::PaymentLink.all diff --git a/examples/payment-links/update.rb b/examples/payment-links/update.rb new file mode 100644 index 0000000..ba5f4f9 --- /dev/null +++ b/examples/payment-links/update.rb @@ -0,0 +1,5 @@ +payment_link = Mollie::PaymentLink.update( + "pl_4Y0eZitmBnQ6IDoMqZQKh", + description: "Bicycle tires", + archived: true +) diff --git a/lib/mollie.rb b/lib/mollie.rb index b7dd461..00c243f 100644 --- a/lib/mollie.rb +++ b/lib/mollie.rb @@ -23,6 +23,7 @@ module Mollie require 'mollie/organization' require 'mollie/partner' require 'mollie/payment' +require 'mollie/payment_link' require 'mollie/permission' require 'mollie/profile' require 'mollie/refund' diff --git a/lib/mollie/base.rb b/lib/mollie/base.rb index 3f85da6..2d63c43 100644 --- a/lib/mollie/base.rb +++ b/lib/mollie/base.rb @@ -71,6 +71,8 @@ def resource_name(parent_id = nil) path.last end end + + alias_method :embedded_resource_name, :resource_name end def update(data = {}) diff --git a/lib/mollie/list.rb b/lib/mollie/list.rb index 0f96f35..a98148b 100644 --- a/lib/mollie/list.rb +++ b/lib/mollie/list.rb @@ -9,7 +9,7 @@ def initialize(list_attributes, klass) @klass = klass list_attributes['items'] ||= if list_attributes['_embedded'] - list_attributes['_embedded'].fetch(klass.resource_name, []) + list_attributes['_embedded'].fetch(klass.embedded_resource_name, []) else [] end diff --git a/lib/mollie/payment_link.rb b/lib/mollie/payment_link.rb new file mode 100644 index 0000000..a2d7389 --- /dev/null +++ b/lib/mollie/payment_link.rb @@ -0,0 +1,70 @@ +module Mollie + class PaymentLink < Base + attr_accessor :id, + :mode, + :description, + :archived, + :redirect_url, + :webhook_url, + :profile_id, + :_links + + attr_reader :amount, + :created_at, + :paid_at, + :updated_at, + :expires_at + + alias_method :links, :_links + + def self.embedded_resource_name(_parent_id = nil) + "payment_links" + end + + def self.resource_name(_parent_id = nil) + "payment-links" + end + + def amount=(amount) + @amount = Mollie::Amount.new(amount) + end + + def archived? + archived + end + + def created_at=(created_at) + @created_at = Time.parse(created_at.to_s) + end + + def paid_at=(paid_at) + @paid_at = Time.parse(paid_at.to_s) + rescue + nil + end + + def updated_at=(updated_at) + @updated_at = Time.parse(updated_at.to_s) + rescue + nil + end + + def expires_at=(expires_at) + @expires_at = Time.parse(expires_at.to_s) + rescue + nil + end + + def payment_link + Util.extract_url(links, "payment_link") + end + + def payments(options = {}) + resource_url = Util.extract_url(links, "self") + payments_url = File.join(resource_url, "/payments") + + response = Mollie::Client.instance.perform_http_call("GET", payments_url, nil, {}, options) + Mollie::List.new(response, Mollie::Payment) + end + end +end diff --git a/test/fixtures/payment_links/create.json b/test/fixtures/payment_links/create.json new file mode 100644 index 0000000..75888a2 --- /dev/null +++ b/test/fixtures/payment_links/create.json @@ -0,0 +1,7 @@ +{ + "description": "Bicycle tires", + "amount": { + "currency": "EUR", + "value": "24.95" + } +} diff --git a/test/fixtures/payment_links/get.json b/test/fixtures/payment_links/get.json new file mode 100644 index 0000000..aaf5dc4 --- /dev/null +++ b/test/fixtures/payment_links/get.json @@ -0,0 +1,32 @@ +{ + "resource": "payment-link", + "id": "pl_4Y0eZitmBnQ6IDoMqZQKh", + "mode": "test", + "description": "Bicycle tires", + "archived": false, + "profile_id": "pfl_QkEhN94Ba", + "amount": { + "currency": "EUR", + "value": "24.95" + }, + "webhook_url": "https://webshop.example.org/payment-links/webhook", + "redirect_url": "https://webshop.example.org/thanks", + "created_at": "2024-09-24T12:16:44+00:00", + "paid_at": null, + "updated_at": null, + "expires_at": null, + "_links": { + "self": { + "href": "https://api.mollie.com/v2/payment-links/pl_4Y0eZitmBnQ6IDoMqZQKh", + "type": "application/hal+json" + }, + "paymentLink": { + "href": "https://paymentlink.mollie.com/payment/4Y0eZitmBnQ6IDoMqZQKh", + "type": "text/html" + }, + "documentation": { + "href": "https://docs.mollie.com/reference/v2/payment-links-api/get-payment-link", + "type": "text/html" + } + } +} diff --git a/test/fixtures/payment_links/list-payments.json b/test/fixtures/payment_links/list-payments.json new file mode 100644 index 0000000..703c970 --- /dev/null +++ b/test/fixtures/payment_links/list-payments.json @@ -0,0 +1,31 @@ +{ + "count": 3, + "_embedded": { + "payments": [ + { + "resource": "payment", + "id": "tr_one" + }, + { + "resource": "payment", + "id": "tr_two" + }, + { + "resource": "payment", + "id": "tr_three" + } + ] + }, + "_links": { + "self": { + "href": "https://api.mollie.com/v2/payment-links/pl_4Y0eZitmBnQ6IDoMqZQKh/payments?limit=50", + "type": "application/hal+json" + }, + "previous": null, + "next": null, + "documentation": { + "href": "https://docs.mollie.com/reference/get-payment-link-payments", + "type": "text/html" + } + } +} diff --git a/test/fixtures/payment_links/list.json b/test/fixtures/payment_links/list.json new file mode 100644 index 0000000..7fafd13 --- /dev/null +++ b/test/fixtures/payment_links/list.json @@ -0,0 +1,31 @@ +{ + "count": 3, + "_embedded": { + "payment_links": [ + { + "resource": "payment-link", + "id": "pl_one" + }, + { + "resource": "payment-link", + "id": "pl_two" + }, + { + "resource": "payment-link", + "id": "pl_three" + } + ] + }, + "_links": { + "self": { + "href": "https://api.mollie.com/v2/payment-links?limit=50", + "type": "application/hal+json" + }, + "previous": null, + "next": null, + "documentation": { + "href": "https://docs.mollie.com/reference/v2/payment-links-api/list-payment-links", + "type": "text/html" + } + } +} diff --git a/test/fixtures/payment_links/update.json b/test/fixtures/payment_links/update.json new file mode 100644 index 0000000..2722a36 --- /dev/null +++ b/test/fixtures/payment_links/update.json @@ -0,0 +1,4 @@ +{ + "description": "Car tires", + "archived": true +} diff --git a/test/mollie/payment_link_test.rb b/test/mollie/payment_link_test.rb new file mode 100644 index 0000000..04f1638 --- /dev/null +++ b/test/mollie/payment_link_test.rb @@ -0,0 +1,100 @@ +require "helper" + +module Mollie + class PaymentLinkTest < Test::Unit::TestCase + CREATE_PAYMENT_LINK = read_fixture("payment_links/create.json") + GET_PAYMENT_LINK = read_fixture("payment_links/get.json") + UPDATE_PAYMENT_LINK = read_fixture("payment_links/update.json") + LIST_PAYMENT_LINKS = read_fixture("payment_links/list.json") + LIST_PAYMENT_LINK_PAYMENTS = read_fixture("payment_links/list-payments.json") + + def test_archived? + assert PaymentLink.new(archived: true).archived? + assert_false PaymentLink.new(archived: false).archived? + end + + def test_create_payment + minified_body = JSON.parse(CREATE_PAYMENT_LINK).to_json + stub_request(:post, "https://api.mollie.com/v2/payment-links") + .with(body: minified_body) + .to_return(status: 201, body: GET_PAYMENT_LINK, headers: {}) + + payment_link = PaymentLink.create( + description: "Bicycle tires", + amount: {currency: "EUR", value: "24.95"} + ) + + assert_kind_of PaymentLink, payment_link + assert_equal "pl_4Y0eZitmBnQ6IDoMqZQKh", payment_link.id + end + + def test_get_payment_link + stub_request(:get, "https://api.mollie.com/v2/payment-links/pl_4Y0eZitmBnQ6IDoMqZQKh") + .to_return(status: 200, body: GET_PAYMENT_LINK, headers: {}) + + payment_link = PaymentLink.get("pl_4Y0eZitmBnQ6IDoMqZQKh") + + assert_equal "pl_4Y0eZitmBnQ6IDoMqZQKh", payment_link.id + assert_equal "test", payment_link.mode + assert_equal "Bicycle tires", payment_link.description + assert_false payment_link.archived + assert_equal "pfl_QkEhN94Ba", payment_link.profile_id + assert_equal 24.95, payment_link.amount.value + assert_equal "EUR", payment_link.amount.currency + assert_equal "https://webshop.example.org/payment-links/webhook", payment_link.webhook_url + assert_equal "https://webshop.example.org/thanks", payment_link.redirect_url + assert_equal Time.parse("2024-09-24T12:16:44+00:00"), payment_link.created_at + assert_equal "https://paymentlink.mollie.com/payment/4Y0eZitmBnQ6IDoMqZQKh", payment_link.payment_link + assert_nil payment_link.paid_at + assert_nil payment_link.updated_at + assert_nil payment_link.expires_at + end + + def test_update_payment_link + minified_body = JSON.parse(UPDATE_PAYMENT_LINK).to_json + stub_request(:patch, 'https://api.mollie.com/v2/payment-links/pl_4Y0eZitmBnQ6IDoMqZQKh') + .with(body: minified_body) + .to_return(status: 200, body: GET_PAYMENT_LINK, headers: {}) + + payment_link = PaymentLink.update("pl_4Y0eZitmBnQ6IDoMqZQKh", JSON.parse(UPDATE_PAYMENT_LINK)) + + assert_kind_of PaymentLink, payment_link + assert_equal "pl_4Y0eZitmBnQ6IDoMqZQKh", payment_link.id + end + + def test_delete_payment_link + stub_request(:delete, 'https://api.mollie.com/v2/payment-links/pl_4Y0eZitmBnQ6IDoMqZQKh') + .to_return(status: 204, body: GET_PAYMENT_LINK, headers: {}) + + payment_link = PaymentLink.delete("pl_4Y0eZitmBnQ6IDoMqZQKh") + assert_nil payment_link + end + + def test_list_payment_links + stub_request(:get, "https://api.mollie.com/v2/payment-links") + .to_return(status: 200, body: LIST_PAYMENT_LINKS, headers: {}) + + payment_links = PaymentLink.all + assert_equal 3, payment_links.size + assert_equal "pl_one", payment_links[0].id + assert_equal "pl_two", payment_links[1].id + assert_equal "pl_three", payment_links[2].id + end + + def test_list_payment_link_payments + stub_request(:get, "https://api.mollie.com/v2/payment-links/pl_4Y0eZitmBnQ6IDoMqZQKh") + .to_return(status: 200, body: GET_PAYMENT_LINK, headers: {}) + + stub_request(:get, "https://api.mollie.com/v2/payment-links/pl_4Y0eZitmBnQ6IDoMqZQKh/payments") + .to_return(status: 200, body: LIST_PAYMENT_LINK_PAYMENTS, headers: {}) + + payment_link = PaymentLink.get("pl_4Y0eZitmBnQ6IDoMqZQKh") + payments = payment_link.payments + + assert_equal 3, payments.size + assert_equal "tr_one", payments[0].id + assert_equal "tr_two", payments[1].id + assert_equal "tr_three", payments[2].id + end + end +end