10. Оплата

20 ноября 2017 г. 2:35

Провайдеры Оплаты (Payment Providers) являются простыми классами, которые создают интерфейс между Платёжной Системой (Payment Service Providers, PSP, дословно Сервис-Провайдер Оплаты) (сокращённо ПС) и нашим фреймворком django-shop.

Провайдеры оплаты должны быть унаследованы от Payment Cart Modifier (Платёжный модификатор корзины). Здесь Payment Cart Modifier вычисляет дополнительные сборы в случае, когда выбран платёжный метод. В это время наш класс Payment Provider, взаимодействует с настроенной ПС, всякий раз, когда покупатель посылает запрос о покупке.

В django-SHOP Провайдеры Оплаты обычно располагаются в различных плагинах, поэтому здесь мы будет показывать как создать свой Провайдер Оплаты вместо объяснения конфигурации существующей интеграции Оплаты.

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

10.1. Формы оформления заказа

Так как продавец не должен "видеть" вводимую информацию кредитных карт, некоторые ПС требуют, чтобы покупатели перенаправлялись на их сайт и вводили там номера карт. У некоторых пользователей может возникнуть беспокойство, потому что они визуально покидают текущий сайт магазина.

Чтобы этого не происходило, другие ПС позволяют создавать HTML-форму, данные которой отправляются на их сайт для решения задачи по оплате. Это работает, благодаря POST запросу, который возвращается назад к клиенту. Другие провайдеры используют Javascript для представления и возврата платёжного токена клиенту, который сам дальше отправляет этот токен на сайт магазина.

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

В django-SHOP используется Javascript во время операции покупки. Попробуем объяснить, как это происходит.

10.1.1. Операция покупки

Во время оформления заказа клиенты конечным шагом клиентов может быть щёлчок по кнопке "Купить сейчас". Эта кнопка принадлежит контроллеру AngularJS, предоставленного директивой shop-dialog-proceed. Это может выглядеть так:

<button shop-dialog-proceed ng-click=”proceedWith(‘PURCHASE_NOW’)” class=”btn btn-success”>Buy Now</button>

Всякий раз, когда покупатели щёлкают по кнопке, функция proceedWith('PURCHASE_NOW') вызывается в scope контроллера AngularJS, принадлежащего данной директовой.

Эта функция сначала загружает текущие формы оформления заказа на сервер. Там они валидируются, и если всё ОК, то загружают данные (context) оформления заказа назад клиенту. Подробнее: shop.views.checkout.CheckoutViewSet.upload().

Далее, успешный обработчик предыдущего представления смотрит на данное действие. в proceedWith, мы использовали магическое ключевое слово PURCHASE_NOW, который отправляет второе представление на сервер, запрашивая начать операцию покупки (Подробнее: shop.views.checkout.CheckoutViewSet.purchase()). Этот метод определяет провайдера оплаты, выбранного покупателем. Затем он вызывает метод get_payment_request() этого провайдера, который возвращает Javascript-выражение.

На клиенте это возвращенное Javascript-выражение обрабатывается функцией eval() и выполняется. Далее, покупатель обычно начинает подавать платежный запрос, отправляя все данные кредитной карты в данную ПС.

При обработке платежа ПС обычно должны взаимодействовать с инфраструктурой магазина, чтобы сообщить нам об успешности или неудаче платежа. Чтобы связаться с нами, им может понадобиться несколько конечных точек (endpoints). Каждый Провайдер Оплаты может переопределить метод get_urls(), возвращающий список URL-адресов, который затем используется механизмом разрешения URL-адресов Django.

class MyPSP(PaymentProvider):
    namespace = 'my-psp-payment'

    def get_urls(self):
        urlpatterns = [
            url(r'^success$', self.success_view, name='success'),
            url(r'^failure$', self.failure_view, name='failure'),
        ]
        return urlpatterns

    def get_payment_request(self, cart, request):
        js_expression = 'scope.charge().then(function(response) { $window.location.href=response.data.thank_you_url; });'
        return js_expression

    @classmethod
    def success_view(cls, request):
        # одобрение платежа с использованием данных request, возвращённых ПС
        cart = CartModel.objects.get_from_request(request)
        order = OrderModel.objects.create_from_cart(cart, request)
        order.add_paypal_payment(payment.to_dict())
        order.save()
        thank_you_url = OrderModel.objects.get_latest_url()
        return HttpResponseRedirect(thank_you_url)

    @classmethod
    def failure_view(cls, request):
        """Перенаправление в URL, где покупатель информируется об отменённом платеже"""
        cancel_url = Page.objects.public().get(reverse_id='cancel-payment').get_absolute_url()
        return HttpResponseRedirect(cancel_url)
Замечание
Директива shop-dialog-proceed обрабатывает возвращённое Javascript-выражение внутри привязанного then(...)-handler от AngularJS. Это означает, что каждая функция может сама вернуть новое обещание, которое выполнится следующим then(...)-handler.

Как мы видим в этом примере, выполняя произвольный Javascript на клиенте в сочетании с HTTP-обработчиками для любой конечной точки (endpoint), django-SHOP может предложить API, в котором новые ПС не потребуют каких-либо специальных трюков (костылей) для их работоспособности.

Оцените статью

0 из 5 (всего 0 оценок)

captcha
Отмеченные звёздочкой поля ( * ) являются обязательными для заполнения.

Спасибо за ваш отзыв!

После нажатия кнопки "Отправить" ваше сообщение будет доставлено мне на почту.

Автор перевода

Артём Мальцев

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

Права на использование материала, расположенного на этой странице https://vivazzi.pro/ru/django-shop/payment-providers/:

Разрешается копировать материал с указанием её автора и ссылки на оригинал без использования параметра rel="nofollow" в теге <a>. Использование:

Автор перевода: Артём Мальцев
Ссылка на перевод статьи: <a href="https://vivazzi.pro/ru/django-shop/payment-providers/">https://vivazzi.pro/ru/django-shop/payment-providers/</a>

Больше: Правила использования сайта

Представляю вашему вниманию книгу, написанную моим близким другом Максимом Макуриным: Секреты эффективного управления ассортиментом.

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

Комментарии: 3

Дмитрий
Дмитрий

18.07.2018 2:02 #

Привет. Не подскажешь, как подключить яндекс кассу (api) https://github.com/yandex-money/yandex-checkout-sdk-python к django cms ?

Ответить

Артём Мальцев
Артём Мальцев автор

19.07.2018 1:50 #

Приветствую! Сам пока не подключал Яндекс.Кассу, но в принципе у всех платёжек похожий api, поэтому сам процесс подключения не должен вызывать трудностей. Другое дело как в django-cms внедрить. В общем случае могу сказать следующее - есть два способа внедрения:

  1. Прикрутить платёжку на странице оформления заказа, как это сделано в демо-магазине проекта через stripe. Но тут нужно умудриться как-то связать вместе с angular.
  2. Прикрутить платёжку на странице Просмотра заказа. Когда уже заказ был оформлен, тебя перебрасывает на страницу Спасибо за покупку - там и можно разместить кнопку Оплатить заказ. В этом случае будет без angular, что может быть попроще.

Ответить

Гость
Гость

19.07.2018 2:05 #

Спасибо за ответ, буду пробовать второй вариант

Ответить

Вы можете оставить комментарий как незарегистрированный пользователь.

Но зарегистрировавшись, вы сможете:

  • получать оповещения об ответах
  • просматривать свои комментарии
  • иметь возможность использовать все функции разработанных сервисов

Для комментирования от своего имени войдите или зарегистрируйтесь на сайте Vuspace

Отправить

На данный момент нет специального поиска, поэтому я предлагаю воспользоваться обычной поисковой системой, например, Google, добавив "vivazzi" после своего запроса.

Попробуйте

Выберите валюту для отображения денежных единиц