跳出ping++退款的坑

2023-11-03

近期在项目的开发过程中,需要用到ping++的退款功能,由于使用的版本比官方提供的要低2个小版本,因此问题并不是很大。但是由于官方文档有些内容写的比较含蓄,因此遇到了一些问题。
我们可以通过如下的方式来获取SDK的版本:

>>> import pingpp
>>> pingpp.VERSION
'2.0.7'
>>> pingpp.api_version
'2.0.7'

在官方文档得说明中,我们可以看到这样3句代码:

import pingpp
pingpp.api_key = 'sk_test_ibbTe5jLGCi5rzfH4OqPW9KC'
ch = pingpp.Charge.retrieve('CH-ID')
re = ch.refunds.create(description='desc', amount=1)

入坑

在这里,我们看到我们先导入pingpp库,然后通过赋值的方式将其传入。然后我们通过pingpp得Charge类的retrieve方法获取给定ch_id,然后再根据其refunds属性得create方法传入关键字参数来实现退款的操作。
如果我们没有传入api_key,将得到1个AuthenticationError权限错误:

AuthenticationError: No API key provided. (HINT: set your API key using "pingpp.api_key = <API-KEY>"). You can generate
 API keys from the Ping++ web interface.  See https://pingxx.com for details, or email support@pingxx.com if you have a
ny questions.

在这里,我按照官方提供的方式进行赋值,直接就出现上面的情况了,让人比较纳闷。

出坑

下面我们来看下其实现的源码,在resource模块下的Charge类继承自3个类,分别为CreateableAPIResource, ListableAPIResource,UpdateableAPIResource。其源码如下:

class Charge(CreateableAPIResource, ListableAPIResource,
             UpdateableAPIResource):
    def refund(self, **params):
        ...

而这3个父类继承自APIResource类,而APIResource类继承自PingppObject类,它是1个Pingpp对象。

class CreateableAPIResource(APIResource):
    @classmethod
    def create(cls, api_key=None, **params):
        requestor = api_requestor.APIRequestor(api_key)
        url = cls.class_url()
        response, api_key = requestor.request('post', url, params)
        return convert_to_pingpp_object(response, api_key)

class APIResource(PingppObject):
    @classmethod
    def retrieve(cls, id, api_key=None, **params):
        instance = cls(id, api_key, **params)
        instance.refresh()
        return instance

    def refresh(self):
        self.refresh_from(self.request('get', self.instance_url()))
        return self
    @classmethod
    def class_name(cls):
        ...
        return str(urllib.quote_plus(cls.__name__.lower()))

    @classmethod
    def class_url(cls):
        cls_name = cls.class_name()
        return "/v1/%ss" % (cls_name,)

    def instance_url(self):
        ...
        extn = urllib.quote_plus(id)
        return "%s/%s" % (base, extn)

从上述代码,我们可以发现,我们还可以直接将api_key以关键字参数的形式传入到retrieve方法中。
我们调用Charge类的retrieve方法时,其会生成1个实例,然后调用该实例得refresh方法。而后调研该实例的refresh_from方法,使用get请求,而地址为该实例的url。
因此,最终的url地址为https://api.pingxx.com/v1/charges/,首先class_name方法返回Charge类名的小写名称,而后在class_url方法中进行组装后返回给instance_url方法。
而在调用request方法的过程中,我们会涉及到1个convert_to_pingpp_object方法,其将响应的内容转换为pingpp对象。
通过这种方式我们完成了官方文档中查询Charge对象的操作,即进行如下的操作:

GET https://api.pingxx.com/v1/charges/{CHARGE_ID}

因此,上面ch最终的结果为我们使用API调用后得到的JSON数据结果,而后我们通过ch的refunds属性得到这样1个对象:

 ...
   "refunds": {
    "url": "/v1/charges/ch_xxx/refunds", 
    "has_more": false,
    "object": "list",
    "data": [
      {
        ...
      }
    ]
  }

而这个转换的过程是在refresh_from函数中进行的:

def refresh_from(self, values, api_key=None, partial=False):
        ...
        for k, v in values.iteritems():
            super(PingppObject, self).__setitem__(
                k, convert_to_pingpp_object(v, api_key))

而后我们通过object属性获取到ch.refunds的结果为list。通过如下的方式我们得到的ch.refunds为1个ListObject:

def convert_to_pingpp_object(resp,api_key):
    klass_name = resp.get('object')
    if isinstance(klass_name, basestring):
       klass = types.get(klass_name, PingppObject)

这样,我们在create方法中传入的参数与API文档中创建Refund对象的参数一一对应了。而这些传入的参数将在调用api_requestor模块中得APIRequestor类时传入。其中,url为refund对象中的url属性,即上面的/v1/charges/ch_xxx/refunds
因此,第3行中的关键字参数description和amount正好对应官方文档中的说明。需要提示的是,description参数只能是最大255个unicode字符,不然又会出现一些问题。

总结

其实ping++的SDK是与其API接口对应的,如果你在使用SDK的过程中对其传入的参数不明确,可以查看API文档相应篇章中的说明。不然你会遇到ping++平台给你返回一些让你摸不着头脑的回复。

原文:

http://yuki-onna.github.io/jump-out-of-the-refund-of-ping++/

参考文章:

https://www.pingxx.com/api#api-r-new
https://www.pingxx.com/guidance/server/charge/refund
https://github.com/PingPlusPlus/pingpp-python/blob/2.0.7/example/refund.py

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

跳出ping++退款的坑 的相关文章

随机推荐

  • 02Tcpdump命令详解-网络抓包工具

    1 概述 今天我们要介绍的是一款网络抓包工具tcpdump 重点讨论并介绍一些有用的命令及最佳实践 tcpdump是一个功能最强大 应用最广泛的命令行数据包嗅探器或包分析工具 用于抓取或过滤制定接口接受或发送的TCP IP数据包 tcmpd
  • 42-Docker-Docker命令详解-docker build

    Docker命令详解 docker build 前言 docker build 原理 语法格式 options说明 使用示例 前言 本篇来学习下制作docker镜像的命令 docker build docker build 原理 docke
  • 环境文件复制

    1 yaml复制 package com ybw yaml demo generate import com alibaba fastjson2 JSON import lombok extern slf4j Slf4j import or
  • linux android studio 快捷方式,Android Studio 使用小技巧和快捷键

    Android Studio 使用小技巧和快捷键 Published by xiaosixi on 2016年12月19日 1 书签 Bookmarks 描述 这是一个很有用的功能 让你可以在某处做个标记 书签 方便后面再跳转到此处 调用
  • 【论文速览】ICLR23 - 将图像视为一组点集 Image as Set of Points

    文章目录 研究背景 解决思路 部分实验效果 思考 参考资料 收录于ICLR2023 oral notable top 5 代码地址 https github com ma xu Context Cluster 研究背景 目前计算机视觉领域最
  • 循环代码模型构建方法

    循环结构是源代码程序的重要结构 然而即使是简单的循环程序 也很容易出错 循环中的很多错误往往需要执行多次或者在某些特定的情况下才能被发现 检测这些错误的代价很高 所以需要重点开展对软件循环代码的安全性分析研究 而对循环代码结构进行研究的重要
  • 2018年Android面试题含答案--适合中高级

    1 java中 和equals和hashCode的区别 基本数据类型的 比较的值相等 类的 比较的内存的地址 即是否是同一个对象 在不覆盖equals的情况下 同比较内存地址 原实现也为 如String等重写了equals方法 hashCo
  • 如何学会读论文?送你滑铁卢大学S. Keshav的三轮阅读法

    来源 专知 本文约3100字 建议阅读6分钟 本文为你介绍三轮阅读法 教你如何高效读论文 导读 读论文是从事科学研究与工程等必不可少环节 但是如何高效读论文却有一番讲究 滑铁卢大学S Keshav 撰写了 How to Read a Pap
  • 80 后女程序员拒当「码农」:“转行小说家后,我用 AI 写了 16 本书!”

    省时查报告 专业 及时 全面的行研报告库 省时查方案 专业 及时 全面的营销策划方案库 免费下载 2023年8月份全网热门报告合集 ChatGPT提词示例 让你的ChatGPT聪明100倍 超百页干货资料 AI应用的难点 痛点与未来 202
  • 终止关闭服务端口号 8080为例

    Identify and stop the process that s listening on port 8080 or configure thi 当我们遇到服务器端口号被占用的时候 下一个服务器就带不开了 让人很是烦躁 下面猿猿总结
  • 【华为OD机试真题 python】事件推送【2022 Q4

    题目描述 事件推送 同一个数轴X上有两个点的集合A A1 A2 Am 和B B1 B2 Bn Ai和Bj均为正整数 A B已经按照从小到大排好序 A B均不为空 给定一个距离R 正整数 列出同时满足如下条件的所有 Ai Bj 数对 1 Ai
  • oracle单实例客户端连接的failover功能

    今天测试了一下单实例数据库客户端连接的failover功能 操作系统为red hat 5 5 root localhost cat etc issue Red Hat Enterprise Linux Server release 5 5
  • vue项目树状图的实现

    1 实现背景 项目需要直观的展示元素之间的关系 需要实现一个树状图 数据可视化可以用Echarts HighCharts 但是相关树状图的示例不够直观 且不美观 几种工具之间比较 选择了蚂蚁金服的G6来实现 在开发期间有树状图的示例 之后再
  • 快速排序基本思想及代码实现-史上最通俗易懂的

    来源 我是码农 转载请保留出处和链接 本文链接 http www 54manong com id 1236 1 算法思想 快速排序是C R A Hoare于1962年提出的一种划分交换排序 它采用了一种分治的策略 通常称其为分治法 Divi
  • MQTT遗愿(last will) paho.mqtt实现

    一 MQTT遗嘱 MQTT 可以设置遗嘱 客户端在连接Broker的时候将遗嘱内容 也是topic payload形式 遗嘱也有一个主题 发送给Broker并保存在Broker中 当客户端因为非正常原因断开与Broker的连接时 Broke
  • 进程的相概念(linux系统编程)

    什么是程序 什么是进程 有什么区别 程序是静态的概念 gcc xx x o pro 磁盘中生成的pro就是程序 进程是程序的一次运行活动 通俗的讲就是程序跑起来了 系统中就多了一个进程 在Linux里面怎么查看系统中有哪些进程 使用ps指令
  • linux的超级管理用户

    超级管理用户 也称为root用户 是Linux系统中最高权限用户 root用户具有完全控制系统的权限 可以执行任何操作 包括管理文件 修改配置 安装软件等 下面是root用户的用法大全 切换到root用户 在终端中输入以下命令 su roo
  • 青龙面板使用教程,以及安装

    1 青龙面板使用教程 以及安装 首先青龙面板是在docker里面的 我们要安装一个docker 我这里只有debian 11 安装的教程 如何在debian11上安装docker 知乎 这个文章不错了 按命令执行就好了 其他操作系统的 去网
  • K8S-11--prometheus--(监控基础/prometheus基础/grafana/promQL/exporter/cadvisor)

    一 监控基础 一 监控简介 监控模型 端监控 业务层监控 应用层监控 中间件监控 系统层监控 1 监控概述 web监控 打开速度 URL打开状态码 API接口可用性 业务监控 订单交易量 活跃用户量 支付量 中间件监控 数据库 redis
  • 跳出ping++退款的坑

    近期在项目的开发过程中 需要用到ping 的退款功能 由于使用的版本比官方提供的要低2个小版本 因此问题并不是很大 但是由于官方文档有些内容写的比较含蓄 因此遇到了一些问题 我们可以通过如下的方式来获取SDK的版本 gt gt gt imp