npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

waft-payment

v0.1.3

Published

Payment components for Waft App.

Readme

Waft 收银台

Waft 应用提供收银台能力。

功能特性

  • 支持 支付宝 扫码支付
  • 支持两种展示形式
    • 内嵌:极简的二维码样式
    • 浮窗:内置统一的浮窗样式,除了二维码,同时展示更多的订单信息(订单金额、商户名称等)

接入说明

安装

npm install --save waft-payment

API

参数说明

| 属性 | 类型 | 必填 | 说明 | |---|---|---|---| | sellerId | i64 | 是 | 商户淘宝 ID | | content | string | 是 | 支付内容(内容的字段说明见下方),以 JSON 字符串表示 | | sign | string | 是 | 根据商户 RSA 私钥对 content 的签名,平台会根据商户提交的公钥进行验签(加签、验签方式见下方) | | size | i64 | 否 | (仅内嵌形式下可用)二维码的宽高,默认为 200 | | onStatus | Function | 否 | 订单支付状态回调(状态枚举值见下方) | | requestNewOrder | Function | 是 | (仅浮窗形式下可用)请求订单刷新时,该回调会执行 |

content 支付内容字段说明:

| 属性 | 类型 | 必填 | 说明 | |---|---|---|---| | sellerId | i64 | 是 | 商户淘宝 ID | | amount | i64 | 是 | 订单金额 (单位:分) | | outItemId | string | 是 | 商户的商品 ID | | outItemName | string | 是 | 商户售卖的商品名称 | | outOrderId | string | 是 | 商户订单号 | | payExpireTime | string | 是 | 订单的超时时间(如:2049-12-30 23:59:59) |

订单状态(status)说明:

  • 等待未超时:

| 状态值 | 说明 | |---|---| | 100 | 天猫精灵侧订单创建成功 | | 200 | 交易创单成功 | | 250 | 交易创单失败 | | 300 | 支付创单成功 | | 350 | 支付创单失败 | | 400 | 用户支付成功 | | 450 | 用户支付失败 | | 470 | 用户待支付 |

this.addEventListener('onStatus', (e: Event) => {
  const current = (e as MessageEvent).data
  // { "status": 300 }
  // { "status": 350, "failMsg": "订单创建失败的原因" }
  console.log(current)
})
  • 等待超时:

超时指的是订单创建成功后,长时间处于未支付状态。目前的等待时长约 3-4 分钟,超过这个时间,需创建新的订单。

this.addEventListener('onStatus', (e: Event) => {
  const current = (e as MessageEvent).data
  // { "isTimeout": true }
  console.log(current)
})

如何使用

在需要使用支付组件的页面(比如 pages/index.json)中,声明以下组件:

  • x-payment-qrcode 以内嵌形式展示支付二维码
  • x-payment-drawer 以浮窗形式展示支付二维码
{
  "usingComponents": {
    "x-payment-qrcode": "waft-payment/assembly/qrcode/qrcode",
    "x-payment-drawer": "waft-payment/assembly/drawer/drawer"
  }
}

pages/index.json 中添加相关业务逻辑处理:

import { Page, Props, Event, MessageEvent, console } from 'waft'
import { JSONObject } from 'waft-json'
import { PaymentDrawer } from 'waft-payment'

export class Demo extends Page {
  constructor(props: Props) {
    super(props)

    const state = new JSONObject()
    state.set('sellerId', 0)
    state.set('content', '')
    state.set('sign', '')

    this.setState(state)

    // 创建订单,并渲染内嵌支付二维码
    this.addEventListener('createEmbeddedPayment', (e: Event, target) => {
      const _this = target as Demo
      _this.createEmbeddedQrCode()
    })

    // 创建订单,并打开浮窗展示支付二维码
    this.addEventListener('createPopupPayment', (e: Event, target) => {
      const _this = target as Demo
      _this.createPopupQrCode()
    })

    // (仅在浮窗形式下用到)点击刷新当前订单
    this.addEventListener('requestNewOrder', (e: Event, target) => {
      const _this = target as Demo
      _this.refreshPopupQrCode()
    })

    // 这里可获取当前订单的状态
    this.addEventListener('onStatus', (e: Event) => {
      const current = (e as MessageEvent).data
      // { "status": 300 }
      // { "status": 350, "failMsg": "订单创建失败的原因" }
      // { "isTimeout": true } 等待超时,订单仍未支付
      console.log(current)
    })
  }

  createEmbeddedQrCode(): void {
    /**
     * 注意:内嵌二维码 `didMount` 后不会响应后续 `props` 的更新
     * 如果你想更新订单,需先将组件卸载(比如,本例子中可将订单参数重置为空)
     * 然后根据新的参数 (content / sign) 再渲染新的组件
     */
    if (this.state.getString(sign) != '') {
      const nextState = new JSONObject()
      nextState.set('sellerId', 0)
      nextState.set('content', '')
      nextState.set('sign', '')
      this.setState(nextState)
    }

    setTimeout((_, target) => {
      const _this = target as Demo
      const orderParams = _this.generateOrderParams()
      _this.setState(orderParams)
    }, 0, this)
  }

  createPopupQrCode(): void {
    const orderParams = this.generateOrderParams()
    const sellerId = orderParams.getInteger('sellerId')
    const content = orderParams.getString('content')
    const sign = orderParams.getString('sign')

    PaymentDrawer.open(sellerId, content, sign)
  }

  refreshPopupQrCode(): void {
    const orderParams = this.generateOrderParams()
    const sellerId = orderParams.getInteger('sellerId')
    const content = orderParams.getString('content')
    const sign = orderParams.getString('sign')

    PaymentDrawer.refresh(sellerId, content, sign)
  }

  generateOrderParams(): JSONObject {
    const sellerId = 123 // 商户淘宝 ID
    
    const contentParams = new JSONObject()
  	contentParams.set('sellerId', sellerId) // 商户淘宝ID
    contentParams.set('amount', 1) // 订单金额:1 分钱
  	contentParams.set('outItemId', '123') // 商品 ID
  	contentParams.set('outItemName', '商品名称') // 商品名称
  	contentParams.set('outOrderId', 'abc') // 订单ID
    /**
     * 订单的过期时间:超过这个时间,该笔订单将不能被支付
     * 注意:每个商户的 “待支付订单” 有数量限制
     * 建议不要将过期时间设置得太久,以避免占用限额,导致无法创建新的订单
     */
  	contentParams.set('payExpireTime', '2049-12-30 23:59:59')

  	const content = contentParams.toString() // 该字段为 JSON 字符串形式
    
    // 根据 `content` 生成签名
  	const sign = 'xxx'

    const orderParams = new JSONObject()
    orderParams.set('sellerId', sellerId)
    orderParams.set('content', content)
    orderParams.set('sign', sign)

    return orderParams
  }
}

pages/index.axml 中使用组件:


<!-- 渲染内嵌形式的支付二维码 -->
<view>
  <view onTap="createEmbeddedPayment">创建订单(内嵌二维码)</view>
  <x-payment-qrcode 
    a:if="{{ sellerId && content && sign }}" 
    sellerId="{{ sellerId }}" 
    content="{{ content }}" 
    sign="{{ sign }}"
    onStatus="onPaySuccess" 
  ></x-payment-qrcode>
</view>

<!-- 以浮窗形式打开支付二维码 -->
<view>
  <view onTap="createPopupPayment">创建订单(浮窗)</view>
  <x-payment-drawer 
    requestNewOrder="requestNewOrder" 
    onStatus="onPaySuccess"
  ></x-payment-drawer>
</view>

加签验签说明

// 通过支付宝 SDK 提供的工具类进行加签验签操作
// 可以在 maven 中央仓库下载到,版本选择 3.7.80.ALL 以上即可
// https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java

<dependency>
  <groupId>alipay-sdk-java</groupId>
  <artifactId>alipay-sdk-java</artifactId>
  <version>3.7.80.ALL</version>
</dependency>

// content:需要加签的业务参数,以 JSON 字符串表示

// 加签
String sign = AlipaySignature.rsaSign(content, sysPriKey, "UTF-8", "RSA");

// 验签
boolean signCheck = AlipaySignature.rsaCheck(content, sign2, sysPubKey, "UTF-8", "RSA");

支付状态 HTTP 回调

点击查看参考文档