From 30830b56fde61292abe6b513abe360c2a65f5c6a Mon Sep 17 00:00:00 2001 From: Sylvain Date: Thu, 1 Apr 2021 18:20:26 +0200 Subject: [PATCH] PayZen REST API wrapper ruby + live test keys while configuring --- app/controllers/api/payzen_controller.rb | 17 +++++++ app/frontend/src/javascript/api/payzen.ts | 10 +++++ .../components/payzen-keys-form.tsx | 38 ++++++++-------- app/policies/payzen_policy.rb | 8 ++++ app/views/api/payzen/sdk_test.json.jbuilder | 3 ++ config/routes.rb | 3 ++ lib/pay_zen/charge.rb | 18 ++++++++ lib/pay_zen/client.rb | 44 +++++++++++++++++++ 8 files changed, 122 insertions(+), 19 deletions(-) create mode 100644 app/controllers/api/payzen_controller.rb create mode 100644 app/frontend/src/javascript/api/payzen.ts create mode 100644 app/policies/payzen_policy.rb create mode 100644 app/views/api/payzen/sdk_test.json.jbuilder create mode 100644 lib/pay_zen/charge.rb create mode 100644 lib/pay_zen/client.rb diff --git a/app/controllers/api/payzen_controller.rb b/app/controllers/api/payzen_controller.rb new file mode 100644 index 000000000..ea13597a6 --- /dev/null +++ b/app/controllers/api/payzen_controller.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +# API Controller for accessing PayZen API endpoints through the front-end app +class API::PayzenController < API::ApiController + before_action :authenticate_user! + require 'pay_zen/charge' + + def sdk_test + str = 'fab-manager' + + client = PayZen::Charge.new(base_url: params[:base_url], username: params[:username], password: params[:password]) + res = client.sdk_test(str) + + puts res + @status = res&.answer&.value == str + end +end diff --git a/app/frontend/src/javascript/api/payzen.ts b/app/frontend/src/javascript/api/payzen.ts new file mode 100644 index 000000000..a9f9d31a3 --- /dev/null +++ b/app/frontend/src/javascript/api/payzen.ts @@ -0,0 +1,10 @@ +import apiClient from './api-client'; +import { AxiosResponse } from 'axios'; + +export default class PayzenAPI { + + static async chargeSDKTest(baseURL: string, username: string, password: string): Promise { + const res: AxiosResponse = await apiClient.post('/api/payzen/sdk_test', { base_url: baseURL, username, password }); + return res?.data; + } +} diff --git a/app/frontend/src/javascript/components/payzen-keys-form.tsx b/app/frontend/src/javascript/components/payzen-keys-form.tsx index 4def246bf..01677d1db 100644 --- a/app/frontend/src/javascript/components/payzen-keys-form.tsx +++ b/app/frontend/src/javascript/components/payzen-keys-form.tsx @@ -10,6 +10,7 @@ import { SettingName } from '../models/setting'; import { FabInput } from './fab-input'; import { enableMapSet } from 'immer'; import { useImmer } from 'use-immer'; +import PayzenAPI from '../api/payzen'; enableMapSet(); @@ -38,7 +39,7 @@ const PayZenKeysFormComponent: React.FC = ({ onValidKeys }) if (publicKeyAddOnClassName === validClassName && restApiAddOnClassName === validClassName) { onValidKeys(settings); } - }, [publicKeyAddOnClassName, restApiAddOnClassName]); + }, [publicKeyAddOnClassName, restApiAddOnClassName, settings]); /** * Check if the inputted public key is valid and assign it to the settings if the key is valid @@ -68,24 +69,23 @@ const PayZenKeysFormComponent: React.FC = ({ onValidKeys }) } } if (valid) { - setRestApiAddOn(); - setRestApiAddOnClassName('key-valid'); + PayzenAPI.chargeSDKTest( + settings.get(SettingName.PayZenEndpoint), + settings.get(SettingName.PayZenUsername), + settings.get(SettingName.PayZenPassword) + ).then(result => { + if (result.success) { + setRestApiAddOn(); + setRestApiAddOnClassName('key-valid'); + } else { + setRestApiAddOn(); + setRestApiAddOnClassName('key-invalid'); + } + }, () => { + setRestApiAddOn(); + setRestApiAddOnClassName('key-invalid'); + }); } - // if (!key.match(/^sk_/)) { - // setRestApiAddOn(); - // setRestApiAddOnClassName('key-invalid'); - // return; - // } - // StripeAPI.listAllCharges(key).then(() => { - // setSecretKey(key); - // setSecretKeyAddOn(); - // setSecretKeyAddOnClassName('key-valid'); - // }, reason => { - // if (reason.response.status === 401) { - // setSecretKeyAddOn(); - // setSecretKeyAddOnClassName('key-invalid'); - // } - // }); }; } @@ -142,7 +142,7 @@ const PayZenKeysFormComponent: React.FC = ({ onValidKeys }) } + icon={} value={settings.get(SettingName.PayZenEndpoint)} onChange={testRestApi(SettingName.PayZenEndpoint)} debounce={200} diff --git a/app/policies/payzen_policy.rb b/app/policies/payzen_policy.rb new file mode 100644 index 000000000..cfa841e78 --- /dev/null +++ b/app/policies/payzen_policy.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# Check the access policies for API::PayzenController +class PayzenPolicy < ApplicationPolicy + def sdk_test? + user.admin? + end +end diff --git a/app/views/api/payzen/sdk_test.json.jbuilder b/app/views/api/payzen/sdk_test.json.jbuilder new file mode 100644 index 000000000..2436fc99c --- /dev/null +++ b/app/views/api/payzen/sdk_test.json.jbuilder @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +json.success @status diff --git a/config/routes.rb b/config/routes.rb index 7f47c4d4d..0425e1ff1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -183,6 +183,9 @@ Rails.application.routes.draw do # test MIME type post 'files/mime_type' => 'files#mime' + + # PayZen special endpoint + post 'payzen/sdk_test' => 'payzen#sdk_test' end # rss diff --git a/lib/pay_zen/charge.rb b/lib/pay_zen/charge.rb new file mode 100644 index 000000000..eb8148b6c --- /dev/null +++ b/lib/pay_zen/charge.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'pay_zen/client' + +# Charge/* endpoints of the PayZen REST API +class PayZen::Charge < PayZen::Client + def initialize(base_url: nil, username: nil, password: nil) + super(base_url: base_url, username: username, password: password) + end + + ## + # @see https://payzen.io/fr-FR/rest/V4.0/api/playground/Charge/SDKTest/ + ## + def sdk_test(value) + post('/Charge/SDKTest', value: value) + end +end + diff --git a/lib/pay_zen/client.rb b/lib/pay_zen/client.rb new file mode 100644 index 000000000..1550ca8c0 --- /dev/null +++ b/lib/pay_zen/client.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +# PayZen payement gateway +module PayZen; end + +API_PATH = '/api-payment/V4' + +# Client for connecting to the PayZen REST API +class PayZen::Client + def initialize(base_url: nil, username: nil, password: nil) + @base_url = base_url + @username = username + @password = password + end + + protected + + def post(rel_url, payload, tmp_base_url: nil, tmp_username: nil, tmp_password: nil) + require 'uri' + require 'net/http' + require 'json' + + uri = URI.join(tmp_base_url || base_url, API_PATH, rel_url) + headers = { + 'Authorization' => authorization_header(tmp_username, tmp_password), + 'Content-Type' => 'application/json' + } + + res = Net::HTTP.post(uri, payload.to_json, headers) + JSON.parse(res.body) if res.is_a?(Net::HTTPSuccess) + end + + def base_url + Setting.get('payzen_endpoint') + end + + def authorization_header(user, passwd) + username = user || Setting.get('payzen_username') + password = passwd || Setting.get('payzen_password') + + credentials = Base64.strict_encode64("#{username}:#{password}") + "Basic #{credentials}" + end +end