【问题标题】:Can I set a default payment gateway and hide radio box for choosing payment gateways in saleor?我可以设置默认支付网关并隐藏单选框以在销售商中选择支付网关吗?
【发布时间】:2019-04-26 16:03:43
【问题描述】:

我一直试图隐藏我的销售商网站的结帐流程,因为我认为在付款前选择支付网关的流程可能会让人们感到困惑。

我搜索了很多文档,并试图理解和修改与付款流程相关的代码近一周。由于我对django框架理解不深,没有成功。

请帮帮我,让我知道一些关于我应该在哪里调查和调查什么的提示。如果可以的话,教我如何设置默认支付网关和隐藏选择支付网关的选项。

我认为这与三个文件有关。

  1. saleor/templates/order/pavement.html 通过修改路面模板,我成功地制作了默认支付网关并隐藏了单选按钮,但是每当它被隐藏时,支付处理也没有进行(在成功支付时,url应该从'http://127.0.0.1:8000/ko/order/[ order token ]/payment/'到 'http://127.0.0.1:8000/ko/order/[ order token ]/payment/[ payment gateway name ]/' 但是当我隐藏单选按钮时,url没有改变。)

  2. saleor/saleor/order/views.py

  3. saleor/saleor/order/forms.py

    我猜支付网关信息是从 payment.html 转移到 views.py 的 start_payment 函数,并且与 forms.py 中的 PaymentsForms 类有些相关。我一直在尝试分析和理解这些代码,但我被卡住了。

'saleor/templates/order/pavement.html' 中的部分代码

            <h3>
              <b>{% trans "Choose payment method" %}</b>
            </h3>
            <div class="checkout__payment-form">
              <form method="post" action="{% url "order:payment" token=order.token %}" class="payment-form radio">
                {% csrf_token %}
                {% for choice in payment_form.gateway %}
                  <div class="radio checkout__payment-form__choice">
                    <label>
                      <div class="card card-default">
                        <div class="card-body">
                          <strong>
                            {{choice}}
                          </strong>
                        </div>
                      </div>
                    </label>
                  </div>
                {% endfor %}
                {% block form_submit %}
                  <button type="submit" class="btn btn-primary">
                    {% trans "Proceed to payment" context "Payment details primary action" %}
                  </button>
                {% endblock %}
              </form>
            </div>

“saleor/saleor/order/views.py”中的“start_payment”函数

@check_order_status
def start_payment(request, order, gateway):
    payment_gateway, connection_params = get_payment_gateway(gateway)
    #payment_gateway, connection_params = get_payment_gateway('Dummy gateway')
    extra_data = {'customer_user_agent': request.META.get('HTTP_USER_AGENT')}
    with transaction.atomic():
        payment = create_payment(
            gateway=gateway,
            currency=order.total.gross.currency,
            email=order.user_email,
            billing_address=order.billing_address,
            customer_ip_address=get_client_ip(request),
            total=order.total.gross.amount,
            order=order,
            extra_data=extra_data)

        if (order.is_fully_paid()
                or payment.charge_status == ChargeStatus.FULLY_REFUNDED):
            return redirect(order.get_absolute_url())

        payment_info = create_payment_information(payment)
        form = payment_gateway.create_form(
            data=request.POST or None,
            payment_information=payment_info,
            connection_params=connection_params)
        if form.is_valid():
            try:
                gateway_process_payment(
                    payment=payment, payment_token=form.get_payment_token())
            except Exception as exc:
                form.add_error(None, str(exc))
            else:
                if order.is_fully_paid():
                    return redirect('order:payment-success', token=order.token)
                return redirect(order.get_absolute_url())

    client_token = payment_gateway.get_client_token(
        connection_params=connection_params)
    ctx = {
        'form': form,
        'payment': payment,
        'client_token': client_token,
        'order': order}
    return TemplateResponse(request, payment_gateway.TEMPLATE_PATH, ctx)

“saleor/saleor/order/forms.py”中的“PaymentsForms”类

PAYMENT_CHOICES = [
    (k, v) for k, v in settings.CHECKOUT_PAYMENT_GATEWAYS.items()]


class PaymentsForm(forms.Form):
    gateway = forms.ChoiceField(
        label=pgettext_lazy('Payments form label', 'Payment Method'),
        choices=PAYMENT_CHOICES,
        initial=PAYMENT_CHOICES[0][0],
        widget=forms.RadioSelect)

我尝试设置默认支付网关并隐藏选择支付网关的单选框,但失败了。

【问题讨论】:

  • 见my answer here。特别是PaymentMethodView.get 方法。它检查是否只有一种方法(您可以在此处放置自己的逻辑来设置默认方法)如果只有一种方法,它只是重定向(并设置默认方法)到结帐过程的下一步,否则,呈现付款方式表单(带有选择/单选按钮)。您无需在表单或模板中隐藏任何内容,只需修改该视图类的 get 方法中的逻辑即可。

标签: saleor


【解决方案1】:

我只修改了几行代码就解决了您的问题。

我开始只选择一个支付网关(对我来说:BrainTree),为此您只需插入您希望在电子商务中允许的支付网关。 修改文件saleor/settings.py中的dictCHECKOUT_PAYMENT_GATEWAYS。

CHECKOUT_PAYMENT_GATEWAYS = {
  BRAINTREE: pgettext_lazy('Payment method name', 'Brain tree')
}

然后,您必须将用户从存在单选按钮的页面重定向到唯一一个付款选项页面。 修改文件saleor/order/views.py 中的函数payment 并添加我称为exist_one_gateway 的第二个函数。

def payment(request, token):
    [...]
    if not order.is_pre_authorized():
        payment_form = PaymentsForm(form_data)
        if payment_form.is_valid():
            payment = payment_form.cleaned_data['gateway']
            return redirect(
                'order:payment', token=order.token, gateway=payment)
        elif exist_one_gateway():
            payment = list(settings.CHECKOUT_PAYMENT_GATEWAYS.items())[0][0]
            return redirect(
                'order:payment', token=order.token, gateway=payment)
    [...]
    return TemplateResponse(request, 'order/payment.html', ctx)


    def exist_one_gateway():
        gateway = list(settings.CHECKOUT_PAYMENT_GATEWAYS.items())
    return len(gateway) == 1

payment 函数适用于两个不同的页面,第一个用于您必须单击要选择的支付网关的单选按钮的页面(我们要跳过的那个),以及特定的付款选项页面。

出于这个原因,我添加了一个条件,如果 payment_form 无效(这意味着没有人提交付款),则验证是否仅存在一个付款选项。如果True,用户将被重定向到上一个文件中选择的特定支付页面。

希望对你有所帮助。

【讨论】:

    猜你喜欢
    • 2016-10-07
    • 2018-10-19
    • 2016-02-09
    • 1970-01-01
    • 2021-07-13
    • 2011-02-27
    • 2015-01-12
    • 2017-07-09
    • 2016-02-25
    相关资源
    最近更新 更多