virtual-payment-uni-pay.uvue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <template>
  2. <view class="content">
  3. <view class="uni-list">
  4. <radio-group @change="applePriceChange">
  5. <view class="uni-list-cell" v-for="(item, index) in productList" :key="index">
  6. <radio :value="item['product_id']" :checked="product_id == item['product_id']" />
  7. <view class="price" @click="applePriceClick(item)">{{item['title']}} {{item['goods_price']}}元</view>
  8. </view>
  9. </radio-group>
  10. </view>
  11. <view class="uni-padding-wrap">
  12. <button class="button btn-pay" @click="createOrder" :loading="loading" :disabled="disabled">立即支付</button>
  13. </view>
  14. <!-- 统一支付组件 -->
  15. <uni-pay ref="payRef" :debug="true" :adpid="adpid"
  16. return-url="/pages/API/request-payment/request-payment/order-detail" @mounted="onMounted" @success="onSuccess"
  17. @fail="onFail" @cancel="onCancel"></uni-pay>
  18. </view>
  19. </template>
  20. <script>
  21. export default {
  22. data() {
  23. return {
  24. order_no: "", // 业务系统订单号(即你自己业务系统的订单表的订单号)
  25. out_trade_no: "", // 插件支付单号
  26. adpid: "1000000001", // uni-ad的广告位id
  27. loading: false, // 支付按钮是否在loading中
  28. disabled: true, // 支付按钮是否禁用
  29. product_id: "" // 用户选择的商品id
  30. }
  31. },
  32. onLoad: function () {
  33. },
  34. onShow() {
  35. },
  36. onUnload() { },
  37. computed: {
  38. // 出售的苹果虚拟商品列表
  39. productList() {
  40. return [
  41. {
  42. "description": "为DCloud提供的免费软件进行赞助",
  43. "goods_price": 1, // 单价(元)
  44. "buy_quantity": 1, // 数量(消耗性类型: 数量默认是1,最大值是10)
  45. "product_id": this.isDebug() ? "uniappx.consumable.sponsor_1" : "uniappx.consumable.sponsor1",
  46. "product_type": "consumable", // 消耗性类型
  47. "title": "消耗性产品:赞助"
  48. },
  49. {
  50. "description": "为DCloud提供的免费软件进行赞助",
  51. "goods_price": 5, // 单价(元)
  52. "buy_quantity": 1, // 数量(消耗性类型: 数量默认是1,最大值是10)
  53. "product_id": this.isDebug() ? "uniappx.consumable.sponsor_50" : "uniappx.consumable.sponsor50",
  54. "product_type": "consumable", // 消耗性类型
  55. "title": "消耗性产品:赞助"
  56. },
  57. {
  58. "description": "为DCloud提供的免费软件进行赞助",
  59. "goods_price": 1, // 单价(元)
  60. "buy_quantity": 1, // 数量(非消耗性: 数量只能是1,且一个该类型产品一个appleId只能购买一次)
  61. "product_id": this.isDebug() ? "uniappx.nonconsumable.sponsorskin_1" : "uniappx.nonconsumable.sponsorskin1",
  62. "product_type": "nonconsumable", // 非消耗性类型
  63. "title": "非消耗性产品: 赞助"
  64. },
  65. // {
  66. // "description": "为DCloud提供的免费软件进行赞助",
  67. // "goods_price": 1, // 单价(元)
  68. // "buy_quantity": 1, // 数量(自动续期订阅产品: 数量只能是1)
  69. // "product_id": this.isDebug() ? "uniappx.autorenewable.monthly_1" : "uniappx.autorenewable.monthly1",
  70. // "product_type": "autorenewable", // 自动续期订阅产品
  71. // "title": "自动续期订阅产品:每月定期赞助", // 注意自动续期订阅产品在沙盒模式下,实际周期会缩短到几分钟续期一次(即现实世界几分钟 = 沙盒世界1个月)
  72. // },
  73. {
  74. "description": "为DCloud提供的免费软件进行赞助",
  75. "goods_price": 1, // 单价(元)
  76. "buy_quantity": 1, // 数量(非自动续期订阅产品: 数量只能是1)
  77. "product_id": this.isDebug() ? "uniappx.nonrenewable.monthly_1" : "uniappx.nonrenewable.monthly1",
  78. "product_type": "nonrenewable", // 非自动续期订阅产品
  79. "title": "非自动续期订阅产品:月赞助",
  80. },
  81. // {
  82. // "description": "为DCloud提供的免费软件进行赞助",
  83. // "goods_price": 1, // 单价(元)
  84. // "buy_quantity": 1, // 数量
  85. // "product_id": "uniappx.nonrenewable.none",
  86. // "product_type": "consumable", // 消耗性类型
  87. // "title": "测试不存在的产品"
  88. // }
  89. ] as Array<UTSJSONObject>
  90. }
  91. },
  92. methods: {
  93. // 支付组件加载完毕后执行
  94. onMounted(insideData : any) {
  95. this.init();
  96. },
  97. // 初始化
  98. init() {
  99. this.product_id = this.productList[0]["product_id"] as string;
  100. this.disabled = false;
  101. let payRef = this.$refs['payRef'] as UniPayComponentPublicInstance;
  102. // 苹果虚拟支付未完成订单检测
  103. payRef.appleiapRestore();
  104. },
  105. /**
  106. * 发起支付
  107. * 在调用此api前,你应该先创建自己的业务系统订单,并获得订单号 order_no,把order_no当参数传给此api,而示例中为了简化跟支付插件无关的代码,这里直接已时间戳生成了order_no
  108. */
  109. createOrder() {
  110. this.order_no = `test` + Date.now();
  111. this.out_trade_no = this.order_no;
  112. let productInfo : UTSJSONObject = this.productList.find((item : UTSJSONObject) : boolean => {
  113. return item['product_id'] == this.product_id;
  114. });
  115. let buy_quantity = productInfo.getNumber('buy_quantity') || 1;
  116. let goods_price = productInfo.getNumber('goods_price');
  117. let product_type = productInfo['product_type'];
  118. // 发起支付
  119. this.$refs.payRef.createOrder({
  120. provider: "appleiap", // 支付供应商(这里固定为appleiap,代表苹果虚拟支付)
  121. order_no: this.order_no, // 业务系统订单号(即你自己业务系统的订单表的订单号)
  122. out_trade_no: this.out_trade_no, // 插件支付单号
  123. type: "appleiap", // 支付回调类型(可自定义,建议填写appleiap)
  124. description: productInfo.description,
  125. total_fee: parseInt((goods_price * 100 * buy_quantity).toFixed(0)), // 插件是以分为单位,故这里需要乘以100
  126. // apple_virtual字段仅苹果虚拟支付生效
  127. apple_virtual: {
  128. product_id: this.product_id, // 产品id
  129. goods_price: goods_price, // 单价
  130. buy_quantity: buy_quantity, // 购买数量
  131. product_type: product_type // 产品类型
  132. },
  133. // 自定义数据
  134. custom: {}
  135. });
  136. },
  137. // 监听事件 - 支付成功
  138. onSuccess(res) {
  139. console.log('success: ', res);
  140. if (res.user_order_success) {
  141. // 代表用户已付款,且你自己写的回调成功并正确执行了
  142. } else {
  143. // 代表用户已付款,但你自己写的回调执行失败(通常是因为你的回调代码有问题)
  144. }
  145. },
  146. onFail(err) {
  147. uni.showModal({
  148. content: `${err.errSubject} : ${err.errCode} : ${err.errMsg}`,
  149. showCancel: false,
  150. title: `发起支付失败`,
  151. });
  152. },
  153. onCancel(err) {
  154. uni.showToast({
  155. title: "用户取消了支付",
  156. icon: 'none'
  157. });
  158. },
  159. // 监听-多选框选中的值改变
  160. applePriceChange(e) {
  161. this.product_id = e.detail.value;
  162. },
  163. applePriceClick(item : any) {
  164. this.product_id = item['product_id'] as string;
  165. },
  166. getPackageName() : string {
  167. const res = uni.getAppBaseInfo();
  168. let packageName : string = ""
  169. // #ifdef APP-ANDROID
  170. packageName = res.packageName
  171. // #endif
  172. // #ifdef APP-IOS
  173. packageName = res.bundleId
  174. // #endif
  175. return packageName
  176. },
  177. isDebug() : boolean {
  178. if (this.getPackageName() == 'io.dcloud.uniappx') {
  179. return true
  180. }
  181. return false
  182. }
  183. }
  184. }
  185. </script>
  186. <style>
  187. .content {
  188. padding: 15px;
  189. }
  190. .button {
  191. background-color: #007aff;
  192. color: #ffffff;
  193. }
  194. .uni-list-cell {
  195. display: flex;
  196. flex-direction: row;
  197. align-items: center;
  198. padding: 10px;
  199. border-bottom: 1px solid #eee;
  200. }
  201. .price {
  202. margin-left: 10px;
  203. }
  204. .btn-pay {
  205. margin-top: 30px;
  206. }
  207. </style>