|
@@ -0,0 +1,114 @@
|
|
|
+#coding=utf-8
|
|
|
+
|
|
|
+from django.db import models
|
|
|
+from django.utils import timezone
|
|
|
+
|
|
|
+from apps.customer.models import Customer
|
|
|
+from apps.product_order.models import ProductOrder
|
|
|
+from apps.product.models import Product
|
|
|
+from apps.customer.models import CustomerWechat
|
|
|
+
|
|
|
+from utils.exceptions import CustomError
|
|
|
+from utils.wechatpay import WechatPay
|
|
|
+
|
|
|
+class Pay(models.Model):
|
|
|
+ WAIT = 1
|
|
|
+ CONFIRM = 2
|
|
|
+ CLOSED = 3
|
|
|
+ STATUS_CHOICES = (
|
|
|
+ (WAIT, u'待付款'),
|
|
|
+ (CONFIRM, u'已付款'),
|
|
|
+ (CLOSED, u'已关闭'),
|
|
|
+ )
|
|
|
+ no = models.CharField(max_length=64, verbose_name=u"单号")
|
|
|
+ create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now)
|
|
|
+ customer = models.ForeignKey(Customer, verbose_name=u'客户', on_delete=models.PROTECT)
|
|
|
+ status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, verbose_name=u"支付状态")
|
|
|
+ precreate_amount = models.BigIntegerField(verbose_name=u"预支付金额")
|
|
|
+ amount = models.BigIntegerField(verbose_name=u"实际支付金额", null=True)
|
|
|
+
|
|
|
+ class Meta:
|
|
|
+ db_table = "pay"
|
|
|
+ verbose_name = u"支付"
|
|
|
+ ordering = ('-id',)
|
|
|
+ index_together = (
|
|
|
+ 'create_time',
|
|
|
+ 'status',
|
|
|
+ )
|
|
|
+ unique_together = (
|
|
|
+ 'no',
|
|
|
+ )
|
|
|
+ default_permissions = ()
|
|
|
+
|
|
|
+ def payClosed(self):
|
|
|
+ if self.status != Pay.WAIT:
|
|
|
+ return
|
|
|
+
|
|
|
+ self.status = Pay.CLOSED
|
|
|
+ self.save()
|
|
|
+ self.updateOrderStatus(ProductOrder.REVOKE)
|
|
|
+
|
|
|
+ def payConfirm(self, amount):
|
|
|
+ if self.status != Pay.WAIT:
|
|
|
+ return
|
|
|
+
|
|
|
+ self.status = Pay.CONFIRM
|
|
|
+ self.amount = amount
|
|
|
+ self.save()
|
|
|
+ self.updateOrderStatus(ProductOrder.PAID)
|
|
|
+
|
|
|
+ def updateOrderStatus(self, status):
|
|
|
+ pay_order = PayProduct.objects.filter(main=self).first()
|
|
|
+ pay_order.order.status = status
|
|
|
+ pay_order.order.save()
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def getByNo(no):
|
|
|
+ instance = Pay.objects.filter(no=no).first()
|
|
|
+ if not instance:
|
|
|
+ raise CustomError(u'未找到相应的支付单!')
|
|
|
+ return instance
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def wechatPay(customer, amount, openid):
|
|
|
+ instance = Pay._addnew(customer, amount)
|
|
|
+ return instance, instance._wechatUnifiedOrder(openid)
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def _addnew(customer, amount):
|
|
|
+ if amount <= 0:
|
|
|
+ raise CustomError(u'无效的付款金额!')
|
|
|
+
|
|
|
+ no = timezone.now().strftime('%y%m%d%H%M%S') + str(customer.id)
|
|
|
+ instance = Pay.objects.create(
|
|
|
+ no=no,
|
|
|
+ customer=customer,
|
|
|
+ status=Pay.WAIT,
|
|
|
+ precreate_amount=amount
|
|
|
+ )
|
|
|
+ return instance
|
|
|
+
|
|
|
+ def _wechatUnifiedOrder(self, openid):
|
|
|
+ wechatpay = WechatPay(self.wechatapp.authorizer_appid, self.wechatapp.tenant_num, self.wechatapp.tenant_key)
|
|
|
+ wechatpay.unifiedOrder(self.no, self.precreate_amount, openid)
|
|
|
+ data = wechatpay.getAppString()
|
|
|
+ return data
|
|
|
+
|
|
|
+
|
|
|
+class PayProduct(models.Model):
|
|
|
+ main = models.OneToOneField(Pay, verbose_name=u'支付单', on_delete=models.PROTECT, related_name='pay_package_pay')
|
|
|
+ order = models.OneToOneField(ProductOrder, verbose_name=u'商品订单', on_delete=models.PROTECT, related_name='pay_package_order')
|
|
|
+
|
|
|
+ class Meta:
|
|
|
+ db_table = "pay_package"
|
|
|
+ verbose_name = u"支付商品"
|
|
|
+ ordering = ('-id',)
|
|
|
+ default_permissions = ()
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def addnew(order, openid):
|
|
|
+ pay, query_string = Pay.wechatPay(order.customer, order.actual_amount, openid)
|
|
|
+ instance = PayProduct.objects.create(main=pay, order=order)
|
|
|
+ return instance, query_string
|
|
|
+
|
|
|
+
|