用户不能互相支付 django-paypal

Posted

技术标签:

【中文标题】用户不能互相支付 django-paypal【英文标题】:Users can't pay each other django-paypal 【发布时间】:2021-01-15 19:49:18 【问题描述】:

我有一个在线商店,用户可以在其中互相付费购买东西,我一直在使用沙盒帐户对其进行测试,但我认为它不起作用。实在想不通问题出在哪里

这是我的views.py:

def payment_process(request, trade_id):
    trade = get_object_or_404(Trade, id=trade_id)
    host = request.get_host()

    paypal_dict = 
        'business': trade.seller.email, 
        'amount': Decimal(trade.price),
        'item_name': trade.filename,
        'invoice': str(trade.id),
        'currency_code': 'USD',
        'notify_url': 'https://'.format(host,
                                           reverse('paypal-ipn')),
        'return_url': 'https:///'.format(host,
                                           *reverse('payment_done', kwargs='trade_id': trade.id)),
        'cancel_return': 'https://'.format(host,
                                              reverse('home')),
    

    form = PayPalPaymentsForm(initial=paypal_dict)
    return render(request, 'payment/payment_process.html', 'trade': trade, 'form': form)


@csrf_exempt
def payment_done(request, trade_id):
    # Do some very important stuff after paying ...
    # It would be really nice if someone can help me with a checker
    messages.success(request, 'Your product is in your inbox now')
    return redirect('trade:inbox')

我的 urls.py:

urlpatterns = [
    path('admin/', admin.site.urls),
    ...
    # Prodbox Payment
    path('payment/process/<int:trade_id>/', payment_views.payment_process, name="payment_process"),
    path('payment/done/<int:trade_id>/', payment_views.payment_done, name="payment_done"),
    # Prodbox packages
    path('paypal/', include('paypal.standard.ipn.urls')),
]

处理支付的模板:

% extends 'users/base.html' %

% block title %Payment Process | Prodbox % endblock title %

% block content %
<div class="container row justify-content-center">
    <div class="shadow-lg p-3 mb-5 col-md-8 bg-white rounded m-4 p-4">
        <section>
            <p>Seller:  trade.seller.email </p>
            <p>Product:  trade.thing </p>
            <p style="color: #2ecc71;">Price: $ trade.price </p>
        </section>
        <section>
            <h4>Pay with PayPal</h4>
             form.render 
        </section>
    </div>
</div>
% endblock content %

在完成支付后将用户重定向到 payment_done 视图是非常非常重要,(如果我有一个检查器在运行完成功能之前检查支付是否完成,那就太好了)

另外,请注意,我强调的是用户使用他们的 PayPal 电子邮件帐户

那么为什么它不起作用?!

额外信息(可能没有帮助)

用户模型:

from django.db import models
from django.contrib.auth.models import AbstractUser, BaseUserManager


class CustomUserManager(BaseUserManager):
    """
    Custom user model manager where email is the unique identifiers
    for authentication instead of usernames.
    """

    def create_user(self, email, password, **extra_fields):
        """
        Create and save a User with the given email and password.
        """
        if not email:
            raise ValueError(_('The Email must be set'))
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save()
        return user

    def create_superuser(self, email, password, **extra_fields):
        """
        Create and save a SuperUser with the given email and password.
        """
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError(_('Superuser must have is_staff=True.'))
        if extra_fields.get('is_superuser') is not True:
            raise ValueError(_('Superuser must have is_superuser=True.'))
        return self.create_user(email, password, **extra_fields)


class User(AbstractUser):
    username = None
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    email = models.EmailField(('email address'), unique=True)
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []
    objects = CustomUserManager()

    def username(self):
        return f'self.first_name self.last_name'
    
    def __str__(self):
        return self.email

settings.py:

AUTH_USER_MODEL = 'users.User'
PAYPAL_RECEIVER_EMAIL = 'zeyadshapan2004@gmail.com'

PAYPAL_TEST = False

local_settings.py:

DEBUG = True
ALLOWED_HOSTS = []
PAYPAL_RECEIVER_EMAIL = 'sb-dabm93302277@personal.example.com'
PAYPAL_TEST = True

【问题讨论】:

【参考方案1】:

您说它不起作用,但没有提供有关问题行为及其不起作用的原因的信息。

但我认为这无关紧要,因为您正在使用糟糕的集成(django-paypal,基于支付标准)来实现您想要的行为,因为付款人返回“非常非常重要” .


您应该切换到的集成是集成 v2/checkout/orders,无论是否使用 Checkout-Python-SDK。您的服务器上需要两条路由,一条用于“设置事务”,一条用于“捕获事务”,记录在此:https://developer.paypal.com/docs/checkout/reference/server-integration/

用于审批的最佳前端 UI 在这里:https://developer.paypal.com/demo/checkout/#/pattern/server。在调用您的 2 个 django 后端路由(通过 fetch)的独立 HTML 文件中使其正常工作,然后将其作为前端集成到您的 django 模板和结帐流程中。

对于一个用户支付另一个用户的功能,请使用payee 对象,记录在此:https://developer.paypal.com/docs/checkout/integration-features/pay-another-account/

【讨论】:

以上是关于用户不能互相支付 django-paypal的主要内容,如果未能解决你的问题,请参考以下文章

支付宝快捷登录接口返回的结果没有类似腾讯和微信的openid,网站不能记录这个用户

策略模式

策略模式

支付宝接口注意事项

策略模式的使用

对魔兽世界支付宝Linux三类软件的简单分析