Demo Taler flow without validating payment yet

This commit is contained in:
Maikel Linke
2026-01-19 14:28:00 +11:00
parent 61e0688392
commit c11b93a4dc
6 changed files with 92 additions and 7 deletions

View File

@@ -0,0 +1,16 @@
# frozen_string_literal: true
module PaymentGateways
class TalerController < BaseController
include OrderCompletion
# The Taler merchant backend has taken the payment.
# Now we just need to confirm that and update our local database
# before finalising the order.
def confirm
payment = Spree::Payment.find(params[:payment_id])
@order = payment.order
process_payment_completion!
end
end
end

View File

@@ -1,5 +1,7 @@
# frozen_string_literal: true
require "taler"
module Spree
class PaymentMethod
# GNU Taler is a distributed, open source payment system.
@@ -32,15 +34,46 @@ module Spree
# https://backend.demo.taler.net/instances/blog/orders/2026..?token=S8Y..&session_id=b0b..
def external_payment_url(options)
order = options.fetch(:order)
total_amount = order&.total || 5
taler_amount = "KUDOS:#{total_amount}"
new_order = client.create_order(taler_amount, "OFN Order", "https://ofn.example.net")
order = client.fetch_order(new_order["order_id"])
order["order_status_url"]
payment = load_payment(order)
payment.source ||= self
payment.response_code ||= create_taler_order(payment)
payment.redirect_auth_url ||= fetch_order_url(payment)
payment.save! if payment.changed?
payment.redirect_auth_url
end
def purchase(_money, _creditcard, _gateway_options)
# TODO: implement
ActiveMerchant::Billing::Response.new(true, "test")
end
private
def load_payment(order)
order.payments.checkout.where(payment_method: self).last
end
def create_taler_order(payment)
# We are ignoring currency for now so that we can test with the
# current demo backend only working with the KUDOS currency.
taler_amount = "KUDOS:#{payment.amount}"
urls = Rails.application.routes.url_helpers
new_order = client.create_order(
taler_amount,
I18n.t("payment_method_taler.order_summary"),
urls.payment_gateways_confirm_taler_url(payment_id: payment.id),
)
new_order["order_id"]
end
def fetch_order_url(payment)
order = client.fetch_order(payment.response_code)
order["order_status_url"]
end
def client
@client ||= ::Taler::Client.new(preferred_backend_url, preferred_api_key)
end

View File

@@ -3502,6 +3502,8 @@ en:
payment_processing_failed: "Payment could not be processed, please check the details you entered"
payment_method_not_supported: "That payment method is unsupported. Please choose another one."
payment_updated: "Payment Updated"
payment_method_taler:
order_summary: "Open Food Network order"
cannot_perform_operation: "Could not update the payment"
action_required: "Action required"
tag_rules: "Tag Rules"

View File

@@ -82,6 +82,8 @@ Openfoodnetwork::Application.routes.draw do
get "/stripe/confirm", to: "stripe#confirm", as: :confirm_stripe
get "/stripe/authorize/:order_number", to: "stripe#authorize", as: :authorize_stripe
get "/taler/:payment_id", to: "taler#confirm", as: :confirm_taler
end
get '/checkout', to: 'checkout#edit'

View File

@@ -11,9 +11,14 @@ RSpec.describe Spree::PaymentMethod::Taler do
}
describe "external_payment_url", vcr: true do
it "retrieves a URL to pay at" do
url = subject.external_payment_url(order: nil)
it "retrieves a URL to pay at and stores it on the payment record" do
order = create(:order_ready_for_confirmation, payment_method: taler)
url = subject.external_payment_url(order:)
expect(url).to match %r{\Ahttps://backend.demo.taler.net/instances/sandb}
payment = order.payments.last.reload
expect(payment.response_code).to match "2026.022-0284X4GE8WKMJ"
expect(payment.redirect_auth_url).to eq url
end
end
end

View File

@@ -0,0 +1,27 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe "/payment_gateways/taler/:id" do
it "completes the order" do
shop = create(:distributor_enterprise)
taler = Spree::PaymentMethod::Taler.create!(
name: "Taler",
environment: "test",
distributors: [shop],
)
order = create(:order_ready_for_confirmation, payment_method: taler)
payment = Spree::Payment.last
payment.update!(
payment_method: taler,
response_code: "taler-order-id:12345",
redirect_auth_url: "https://merchant.backend.where-we-paid.com",
)
get payment_gateways_confirm_taler_path(payment_id: payment.id)
expect(response).to redirect_to(order_path(order, order_token: order.token))
payment.reload
expect(payment.state).to eq "completed"
end
end