微信小程序之退款功能实现---python

官方所需的必备参数:

字段名变量名必填类型示例值描述
小程序IDappidString(32)wx8888888888888888微信分配的小程序ID
商户号mch_idString(32)1900000109微信支付分配的商户号
随机字符串nonce_strString(32)5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,不长于32位。推荐随机数生成算法
签名signString(32)C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名生成算法签名生成算法
签名类型sign_typeString(32)HMAC-SHA256 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5
微信订单号transaction_id二选一 String(32)1217752501201407033233368018微信生成的订单号,在支付通知中有返回
商户订单号out_trade_noString(32)1217752501201407033233368018商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-*@ ,且在同一个商户号下唯一。transaction_id、out_trade_no二选一,如果同时存在优先级:transaction_id> out_trade_no
商户退款单号out_refund_noString(64)1217752501201407033233368018商户系统内部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-*@ ,同一退款单号多次请求只退一笔。
订单金额 total_feeInt100订单总金额,单位为分, 只能为整数,详见支付金额
退款金额refund_feeInt100退款总金额,订单总金额,单位为分,只能为整数,详见支付金额
货币种类refund_fee_typeString(8)CNY 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
退款原因refund_descString(80)商品已售完 若商户传入,会在下发给用户的退款消息中体现退款原因注意:若订单退款金额≤1元,且属于部分退款,则不会在退款消息中体现退款原因
退款资金来源refund_accountString(30)REFUND_SOURCE_RECHARGE_FUNDS仅针对老资金流商户使用REFUND_SOURCE_UNSETTLED_FUNDS—未结算资金退款(默认使用未结算资金退款)REFUND_SOURCE_RECHARGE_FUNDS—可用余额退款
退款结果通知urlnotify_urlString(256)https://weixin.qq.com/notify/异步接收微信支付退款结果通知的回调地址,通知URL必须为外网可访问的url,不允许带参数如果参数中传了notify_url,则商户平台上配置的回调地址将不会生效。

XML举例如下:

<xml>
   <appid>wx2421b1c4370ec43b</appid>
   <mch_id>10000100</mch_id>
   <nonce_str>6cefdb308e1e2e8aabd48cf79e546a02</nonce_str>
   <out_refund_no>1415701182</out_refund_no>
   <out_trade_no>1415757673</out_trade_no>
   <refund_fee>1</refund_fee>
   <total_fee>1</total_fee>
   <transaction_id></transaction_id>
   <sign>FE56DD4AA85C0EECA82C35595A69E153</sign>
</xml>
直接贴demo :

# 请求退款地址
refundUrl = 'https://api.mch.weixin.qq.com/secapi/pay/refund'
# 创建小程序对象, 这些东西都是需要事先准备好的,这个是支付用的
# wxrpay = WXAppPay ( appid=APP_ID, mch_id=APP_MCH_ID, partner_key=APP_PARTNER_KEY )

class RefundUrl ( APIView ):
    def post ( self, request ):
        out_refund_no = request.POST[ 'out_refund_no' ]  # 退款单号
        total_fee = request.POST['total_fee']  # 订单金额
        out_trade_no = request.POST[ 'out_trade_no' ] # 订单号
        refund_fee = request.POST[ 'refund_fee' ]  # 退款金额
        nonce_str = WXUtils.randomStr ()  # 随机32位字符串
        prepay = dict ()
        # params : 都是调用微信退款接口必填的参数
        params = {
            'appid': APP_ID,
            'mch_id': APP_MCH_ID,
            # 'notify_url': "https://www.****.com/refund/", 退款回调地址
            'nonce_str': nonce_str,
            'out_trade_no': out_trade_no,
            'out_refund_no': out_refund_no,
            'refund_fee': int ( float ( refund_fee ) * 100 ),
            'sign_type': 'MD5',
            'total_fee': int ( float ( total_fee ) * 100 )
        }
        #  sign : MD5 的加密签证
        sign = WXUtils.wx_sign ( params )
        # 加密完之后,放入params 进行请求
        params[ 'sign' ] = sign
        xmljson = WXUtils.send_xml_request ( refundUrl, params )
        mes = dict ()
        # 这里呢 我没有用回调地址, 而是直接在这里进行成功和失败判断.
        if xmljson[ 'xml' ][ 'return_code' ] == 'SUCCESS':
            if "err_code" not in xmljson[ 'xml' ]:
                # 微信订单号
                prepay[ 'transaction_id' ] = xmljson[ 'xml' ][ 'transaction_id' ]
                # 商户订单号
                prepay[ 'out_trade_no' ] = xmljson[ 'xml' ][ 'out_trade_no' ]
                # 商户退款单号
                prepay[ 'out_refund_no' ] = xmljson[ 'xml' ][ 'out_refund_no' ]
                # 微信退款单号
                prepay[ 'refund_id' ] = xmljson[ 'xml' ][ 'refund_id' ]
                # 退款总金额,单位为分,可以做部分退款
                prepay[ 'refund_fee' ] = xmljson[ 'xml' ][ 'refund_fee' ]
                # 订单总金额,单位为分,只能为整数
                prepay[ 'total_fee' ] = xmljson[ 'xml' ][ 'total_fee' ]

                logger.info ( {"退单号: {}-退款成功,操作人员: {}, 操作时间: {}".format ( xmljson[ 'xml' ][ 'out_refund_no' ] ,'某某某',
                               now_time) } )
				# __可以在这里直接写你的实际操作业务逻辑...
            else:
                # 错误代码
                mes[ 'code' ] = xmljson[ 'xml' ][ 'err_code' ]
                # 错误代码描述
                mes[ 'desc' ] = xmljson[ 'xml' ][ 'err_code_des' ]

        else:
            mes[ 'code' ] = '500'
            mes[ 'desc' ] = '提交业务失败'
        return Response ( prepay )


class WXUtils ( object ):
    """关于微信支付的小工具"""

    # 随机32位字符串
    @staticmethod
    def randomStr ():
        return ''.join ( random.sample ( string.ascii_letters + string.digits, 32 ) )

    # 微信签名算法函数
    @staticmethod
    def wx_sign ( param ):
        stringA = ""
        ks = sorted ( param.keys () )
        # 排序
        for k in ks:
            stringA += (k + "=" + str ( param[ k ] ) + "&")
        # 拼接商户key
        stringSignTemp = stringA + 'key=' + APP_PARTNER_KEY
        # md5加密
        hash_md5 = hashlib.md5 ( stringSignTemp.encode ( 'utf-8' ) )
        sign = hash_md5.hexdigest ().upper ()
        print ( sign )
        return sign

    # 发送xml请求
    @staticmethod
    def send_xml_request ( url, param ):
        import os
        param = {'xml': param}
        xml = xmltodict.unparse ( param )
        # cert  里面的是证书, 没有证书, 请求会失败的, 具体证书怎么来请看微信开发文档.
        response = requests.post ( url, data=xml.encode ( "utf-8" ), cert=(
            r'地址\apiclient_cert.pem',
            r'地址\apiclient_key.pem'),
                                   headers={"Content-Type": "charset=utf-8"} )
        msg = response.content
        xmlmsg = xmltodict.parse ( msg )
        return xmlmsg


微信退款–官方文档
最简单的退款, 不喜勿喷,若有不妥之处, 还望支出, 大家共同学习!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lonelypatients°

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值