Формирование списка платежных шлюзов для конкретных методов доставки

Платежный шлюзВ одной из статей мы уже рассматривали, как предоставить на выбор только определенные системы оплат для разных магазинов вместо всех доступных. Рекомендуется прочесть ее, перед  тем как приступать к этой, так как тут мы будем ссылаться на некоторые решения, которые уже были описаны.

Проблема

Мы уже установили, что иногда нам необходимы уникальные платежные шлюзы для разных магазинов. Теперь рассмотрим такой случай когда нам необходимо отображать типы оплат не только в зависимости от того какой магазин, а и того какой метод доставки выбран. Давайте рассмотрим конфигурацию наших платежных шлюзов из предыдущей статьи и представим, что у нас есть два метода доставки: POST (Доставка почтовой службой) и STOREDELIVERTY (Самовывоз из магазина). При выборе метода POST мы ожидаем от клиента полной оплаты, после чего отправляем ему товар. При выборе метода доставки STOREDELIVERTY клиент платит за товар в магазине при самовывозе. Следовательно, мы сталкиваемся с похожей проблемой, когда не все типы оплат должны быть доступны для различных методов доставки.  Например, если выбран метод доставки POST, то способ оплаты STORECOLLECT (Оплата в магазине) не должен предлагаться.

Следовательно, для метода доставки POST мы предоставляем только платежные шлюзы PGFR или PGUS, для  STOREDELIVERTY – только STORECOLLECT.

Чтобы это реализовать мы будем использовать пользовательские атрибуты для объекта Shop и установим некую псевдо связь между типами оплат и методами доставок.

Настройка методов доставок

Для начала создадим два «перевозчика» (carrier), у которых буду свои методы доставки (carrierSLA):

  1. Создадим carrier Post
  2. Создадим Post carrier SLA для магазина в США (US) и установим поле GUID — POST_USD
  3. Создадим Post carrier SLA для магазина во Франции (FR) и установим поле GUID — POST_EUR
  4. Создадим carrier Store delivery
  5. Создадим Store delivery carrier SLA для магазина в США (US) и установим поле GUID  — STOREDELIVERTY_USD
  6. Создадим Store delivery carrier SLA для магазина во Франции (FR) и установим поле GUID  — STOREDELIVERTY_USD

Все эти значения могут быть добавлены через редактор YUM (или импортированы из csv) без написания дополнительного кода.

Добавление новых атрибутов для объектов Shop

Теперь, когда все методы доставок введены, мы применим к ним тот же механизм, что и для платежных шлюзов из предыдущей статьи. Однако сейчас мы хотим установить связь между методами доставок (SLA) и способами оплат, поэтому нам понадобится атрибут для каждого SLA.

Мы создадим новые атрибуты для объекта Shop со следующими названиями: PAYMENTGATEWAYS_POST_USD, PAYMENTGATEWAYS_POST_EUR, PAYMENTGATEWAYS_STOREDELIVERY_USD и PAYMENTGATEWAYS_STOREDELIVERY_EUR.  Теперь мы можем добавить лейбы платежных шлюзов в эти атрибуты через редактор YUM. Как и в случае с PAYMENTGATEWAYS, атрибуты для SLA будут принимать значения в виде списка разделенного запятыми (comma separated list). Для магазина SHOPFR значение атрибута PAYMENTGATEWAYS_POST_EUR будет:  «PGFR» (Нет необходимости отображать при выборе доставки методом POST другие типы оплат,  например, STORECOLLECT), для PAYMENTGATEWAYS_STOREDELIVERY_EUR – «STORECOLLECT». По такому же принципу мы заполняем атрибуты для SHOPUS: PAYMENTGATEWAYS_POST_USD – «PGUS», PAYMENTGATEWAYS_STOREDELIVERY_USD – «STORECOLLECT».

Пример кода

Теперь для каждого объекта Shop мы можем запросить наши атрибуты для методов доставок (SLA) и получить список доступных платежных шлюзов. Для этого мы внесем следующие изменения в метод CheckoutPage.createPaymentFragment() для дополнительной обработки списка доступных оплат:

...
finalAttrValueShop aymentGatewaysLabels = ApplicationDirector.getCurrentShop().getAttributeByCode("PAYMENTGATEWAYS");
finalCarrierSla sla = carrierSlaService.findById(orderInfo.getCarrierSlaId());
finalAttrValueShop shippingMethodPaymentGatewaysLabels =ApplicationDirector.getCurrentShop().getAttributeByCode("PAYMENTGATEWAYS_"+ sla.getGuid());

finalList<PaymentGatewayDescriptor> allowedPaymentGateways = paymentModulesManager.getPaymentGatewaysDescriptors(false);
finalString shippingMethodAllowed = shippingMethodPaymentGatewaysLabels !=null&& shippingMethodPaymentGatewaysLabels.getVal()!=null&& shippingMethodPaymentGatewaysLabels.getVal().length()>0? shippingMethodPaymentGatewaysLabels.getVal():null;
finalString shopAllowed = paymentGatewaysLabels !=null&& paymentGatewaysLabels.getVal()!=null&&
paymentGatewaysLabels.getVal().length()>0? paymentGatewaysLabels.getVal():null;

finalIterator<PaymentGatewayDescriptor> itPayments = allowedPaymentGateways.iterator();
while(itPayments.hasNext()){
finalPaymentGatewayDescriptor current = itPayments.next();
finalboolean isShopAllowed =(shopAllowed ==null)||(shopAllowed !=null&& shopAllowed.contains(current.getLabel()));
finalboolean isShippingMethodAllowed =(shippingMethodAllowed ==null)||(shippingMethodAllowed !=null&& shippingMethodAllowed.contains(current.getLabel()));
if(!isShopAllowed ||!isShippingMethodAllowed){
itPayments.remove();
}
}

finalAbstractChoice<PaymentGatewayDescriptor,PaymentGatewayDescriptor> gatewayDescriptorDropDownChoice =
newDropDownChoice<PaymentGatewayDescriptor>(
PAYMENT_FRAGMENT_GATEWAY_CHECKBOX,
newPaymentGatewayDescriptorModel(
newPropertyModel<String>(orderInfo,»paymentGatewayLabel»),
allowedPaymentGateways
),
allowedPaymentGateways){

Как и в случае с типами оплат в предыдущей статье, мы сравниваем типы оплат доступные для конкретного магазина и конкретно выбранного метода доставки с общим списком оплат и убираем из последнего те, которые отсутствуют в нашем списке.

Данное изменение позволяет нам добавлять новые платежные шлюзы, новые методы доставок и с легкостью устанавливать между ними связь используя редактором YUM без написания дополнительного кода.

Фильтр платежных шлюзов доступных только для конкретного магазина

Платежный шлюзВ платформе YC все платежные шлюзы общие для всех магазинов (объектов Shop). Это архитектурное решение было принято исходя из того, что, в основном,  все магазины будут иметь стандартный выбор платежных шлюзов. Тем самым, мы также упрощаем весь модуль системы оплат, чтобы он был отделен от других  основных модулей YC, насколько это возможно.

В этой статье мы покажем, как можно с помощью пользовательских атрибутов для объектов Shop указать, какие платежные шлюзы будут доступны для различных магазинов.

Проблема

Рассмотрим такой пример. В платформе YC мы добавили несколько магазинов, каждый из которых направлен на работу с конкретной страной.  Скажем, один магазин на США, другой на Францию. Скорей всего, при выборе оплаты кредитными карточками будет выполняться перенаправление на платежные системы для дальнейшей работы с клиентом по месту жительства. Тогда как способ оплаты в магазине может быть общим.

Итак, кратко о поставленной задаче:

  • 2 магазина: SHOPFR и SHOPUS
  • 3 платежных шлюза: PGFR, PGUS и STORECOLLECT
  • SHOPFR должен предлагать на выбор только: PGFR, STORECOLLECT
  • SHOPUS должен предлагать на выбор только: PGUS, STORECOLLECT

Настройка платежных шлюзов

Первым шагом будет настройках 3-х платежных шлюзов, которые, как было сказано ранее, будут доступны по умолчанию для всех магазинов.

  1. Создайте класс, наследуясь от подходящего класса PaymentGateway, указывая поддерживаемые фичи.
  2. Создайте конфигурационный бин в Spring xml в модуле payment.
  3. Введите необходимые записи параметров TPAYMENTGATEWAYPARAMETER в базе данных yespay.
  4. Добавьте лейбы платежных шлюзов через запятую в атрибут YC_SYSTEM_ACTIVE_PAYMENT_GATEWAYS (или отметьте их в панели оплат в YUM).

Добавление нового атрибута для объектов Shop

Итак, все наши типы оплат доступны для выбора по всем магазинам. Теперь нам нужно указать, какие типы оплат будут доступны для каждого магазина отдельно.

Для этого мы добавим новый атрибут для объектов Shop – PAYMENTGATEWAYS. Атрибут будет принимать значение в виде списка разделенного запятыми (comma separated list). После чего мы можем использовать его через редактор YUM. Для магазина SHOPFR мы внесем значение – «PGFR,STORECOLLECT», для SHOPUS –  «PGUS,STORECOLLECT».

Пример кода

Теперь мы можем запросить наш дополнительный атрибут PAYMENTGATEWAYS и получить список платежных шлюзов для конкретного магазина. Далее внесем изменения в метод CheckoutPage.createPaymentFragment(), где мы добавим дополнительный фильтр для обработки списка оплат.

...
finalAttrValueShop paymentGatewaysLabels =ApplicationDirector.getCurrentShop().getAttributeByCode("PAYMENTGATEWAYS");

finalList<PaymentGatewayDescriptor> allowedPaymentGateways = paymentModulesManager.getPaymentGatewaysDescriptors(false);
finalString shopAllowed = paymentGatewaysLabels !=null&& paymentGatewaysLabels.getVal()!=null&&
paymentGatewaysLabels.getVal().length()>0? paymentGatewaysLabels.getVal():null;

finalIterator<PaymentGatewayDescriptor> itPayments = allowedPaymentGateways.iterator();
while(itPayments.hasNext()){
finalPaymentGatewayDescriptor current = itPayments.next();
finalboolean isShopAllowed =(shopAllowed ==null)||(shopAllowed !=null&&
shopAllowed.contains(current.getLabel()));
if(!isShopAllowed){
itPayments.remove();
}
}

finalAbstractChoice<PaymentGatewayDescriptor,PaymentGatewayDescriptor> gatewayDescriptorDropDownChoice =

newDropDownChoice<PaymentGatewayDescriptor>(
PAYMENT_FRAGMENT_GATEWAY_CHECKBOX,
newPaymentGatewayDescriptorModel(
newPropertyModel<String>(orderInfo,»paymentGatewayLabel»),
allowedPaymentGateways
),
allowedPaymentGateways){

Данный фрагмент кода сравнивает наш список оплат для конкретного магазина с общим списком и убирает из последнего те, которые отсутствуют в нашем списке.

Это все необходимые изменения, остальная часть кода работает корректно.

В этой статье мы рассмотрели некий механизм настройки YC платформы для правильного распределения платежных шлюзов.