首页 > 解决方案 > 如何在 Django 电子商务项目中将 Paypal 添加到付款

问题描述

我一直在寻找将 PayPal 付款添加到我的电子商务项目的最佳方式,但我目前不知道从哪里开始,我已经阅读了 PayPal 文档 https://developer.paypal.com/demo/checkout/#/pattern/radio

目前,当用户将商品添加到购物车时,在结帐页面中有一个要填写的表格,所以在添加地址后有一个单选按钮可以从中选择是继续使用 Stripe 还是 PayPal,所以我的问题是应该我这样做是为了在选择 PayPal 收音机时打开 PayPal 登录窗口?

这是models.py

class Payment(models.Model):
    stripe_charge_id = models.CharField(max_length=50)
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             on_delete=models.SET_NULL, blank=True, null=True)
    amount = models.FloatField()
    timestamp = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.user.username

这是views.py

class CheckoutView(View):
    def get(self, *args, **kwargs):
        try:
            order = Order.objects.get(user=self.request.user, ordered=False)
            form = CheckoutForm()
            context = {
                'form': form,
                'couponform': CouponForm(),
                'order': order,
                'DISPLAY_COUPON_FORM': True
            }
            shipping_address_qs = Address.objects.filter(
                user=self.request.user,
                address_type='S',
                default='True'
            )
            if shipping_address_qs.exists():
                context.update(
                    {'default_shipping_address': shipping_address_qs[0]})

            billing_address_qs = Address.objects.filter(
                user=self.request.user,
                address_type='B',
                default='True'
            )
            if billing_address_qs.exists():
                context.update(
                    {'default_billing_address': billing_address_qs[0]})

            return render(self.request, "checkout.html", context)
        except ObjectDoesNotExist:
            messages.info(self.request, "You do not have an active order")
            return redirect("core:checkout")

    def post(self, *args, **kwargs):
        form = CheckoutForm(self.request.POST or None)
        try:
            order = Order.objects.get(user=self.request.user, ordered=False)
            if form.is_valid():

                use_default_shipping = form.cleaned_data.get(
                    'use_default_shipping')
                if use_default_shipping:
                    print("Using the defualt shipping address")
                    address_qs = Address.objects.filter(
                        user=self.request.user,
                        address_type='S',
                        default=True
                    )
                    if address_qs.exists():
                        shipping_address = address_qs[0]
                        order.shipping_address = shipping_address
                        order.save()
                    else:
                        messages.info(
                            self.request, "No default shipping address available")
                        return redirect('core:checkout')
                else:
                    print("User is entering a new shipping address")
                    shipping_address1 = form.cleaned_data.get(
                        'shipping_address')
                    shipping_address2 = form.cleaned_data.get(
                        'shipping_address2')
                    shipping_province = form.cleaned_data.get(
                        'shipping_province')
                    shipping_country = form.cleaned_data.get(
                        'shipping_country')
                    shipping_postal_code = form.cleaned_data.get(
                        'shipping_postal_code')
                    shipping_phone_number = form.cleaned_data.get(
                        'shipping_phone_number')

                    if is_valid_form([shipping_address1, shipping_province, shipping_country, shipping_postal_code,
                                      shipping_phone_number]):
                        shipping_address = Address(
                            user=self.request.user,
                            street_address=shipping_address1,
                            apartment_address=shipping_address2,
                            province=shipping_province,
                            country=shipping_country,
                            postal_code=shipping_postal_code,
                            phone_number=shipping_phone_number,
                            address_type='S'
                        )
                        shipping_address.save()

                        order.shipping_address = shipping_address
                        order.save()

                        set_default_shipping = form.cleaned_data.get(
                            'set_default_shipping')
                        if set_default_shipping:
                            shipping_address.default = True
                            shipping_address.save()

                    else:
                        messages.info(
                            self.request, "Please fill in the required shipping address fields")

                use_default_billing = form.cleaned_data.get(
                    'use_default_billing')
                same_billing_address = form.cleaned_data.get(
                    'same_billing_address')

                if same_billing_address:
                    billing_address = shipping_address
                    billing_address.pk = None
                    billing_address.save()
                    billing_address.address_type = 'B'
                    billing_address.save()
                    order.billing_address = billing_address
                    order.save()

                elif use_default_billing:
                    print("Using the default billing address")
                    address_qs = Address.objects.filter(
                        user=self.request.user,
                        address_type='B',
                        default='True'
                    )
                    if address_qs.exists():
                        billing_address = address_qs[0]
                        order.billing_address = billing_address
                        order.save()
                    else:
                        messages.info(
                            self.request, "No default billing address available")
                        return redirect('core:checkout')
                else:
                    print("User is entering a new billing address")
                    billing_address1 = form.cleaned_data.get(
                        'billing_address')
                    billing_address2 = form.cleaned_data.get(
                        'billing_address2')
                    billing_province = form.cleaned_data.get(
                        'billing_province')
                    billing_country = form.cleaned_data.get(
                        'billing_country')
                    billing_postal_code = form.cleaned_data.get(
                        'billing_postal_code')
                    billing_phone_number = form.cleaned_data.get(
                        'billing_phone_number')

                    if is_valid_form([billing_address1, billing_province, billing_country, billing_postal_code,
                                      billing_phone_number]):
                        billing_address = Address(
                            user=self.request.user,
                            street_address=billing_address1,
                            apartment_address=billing_address2,
                            province=billing_province,
                            country=billing_country,
                            postal_code=billing_postal_code,
                            phone_number=billing_phone_number,
                            address_type='B'
                        )
                        billing_address.save()

                        order.billing_address = billing_address
                        order.save()

                        set_default_billing = form.cleaned_data.get(
                            'set_default_billing')
                        if set_default_billing:
                            billing_address.default = True
                            billing_address.save()

                    else:
                        messages.info(
                            self.request, "Please fill in the required billing address fields")
                        return redirect('core:checkout')

                payment_option = form.cleaned_data.get('payment_option')

                if payment_option == 'S':
                    return redirect('core:payment', payment_option='stripe')
                elif payment_option == 'P':
                    return redirect('core:payment', payment_option='paypal')
                else:
                    messages.warning(
                        self.request, "Invalid payment option selected")
                    return redirect('core:checkout')

        except ObjectDoesNotExist:
            messages.warning(self.request, "You do not have an active order")
            return redirect("core:order-summary")

这是forms.py

PAYMENT_CHOICES = (
    ('S', 'Stripe'),
    ('P', 'Paypal')
)


class CheckoutForm(forms.Form):
    shipping_address = forms.CharField(required=False)
    shipping_address2 = forms.CharField(required=False)
    shipping_province = forms.CharField(required=False)
    shipping_country = CountryField(blank_label='(select country)').formfield(
        required=False,
        widget=CountrySelectWidget(attrs={
            'class': 'custom-select d-block w-100'
        }))
    shipping_postal_code = forms.CharField(required=False)
    shipping_phone_number = forms.CharField(required=False)

    billing_address = forms.CharField(required=False)
    billing_address2 = forms.CharField(required=False)
    billing_province = forms.CharField(required=False)
    billing_country = CountryField(blank_label='(select country)').formfield(
        required=False,
        widget=CountrySelectWidget(attrs={
            'class': 'custom-select d-block w-100'
        }))
    billing_postal_code = forms.CharField(required=False)
    billing_phone_number = forms.CharField(required=False)

    same_billing_address = forms.BooleanField(required=False)
    set_default_shipping = forms.BooleanField(required=False)
    use_default_shipping = forms.BooleanField(required=False)
    set_default_billing = forms.BooleanField(required=False)
    use_default_billing = forms.BooleanField(required=False)

    payment_option = forms.ChoiceField(
        widget=forms.RadioSelect, choices=PAYMENT_CHOICES)

标签: pythondjangopaypal

解决方案


我建议在您的服务器上创建两条路由,一条用于“设置交易”,一条用于“捕获交易”,记录在此:https ://developer.paypal.com/docs/checkout/reference/server-integration/

选择 PayPal 单选按钮后,您可以让此事件触发 javascript 以取消隐藏 paypal 按钮容器 div,类似于:https ://developer.paypal.com/demo/checkout/#/pattern/server


对于您的用例,layout: 'horizontal'可能是最好的。

有一个示例基本 HTML/JS 实现将其与单选按钮相结合:https ://developer.paypal.com/demo/checkout/#/pattern/radio

值得拥有黄色的 PayPal 按钮和任何本地“替代”支付方式,如 PP Credit PayPal 决定在其旁边显示买家默认可见(单选按钮预选,或者根本没有单选按钮,只显示信用卡表格在它下面)。这将增加您的转化率,点击次数越少越好——PayPal 的卖点是让买家在尽可能少的点击次数中通过安全结账。


推荐阅读