讲师中心 微信公众号
AI工具推荐 视频效率加速

PayFast API 签名生成详解:Python 实现与常见错误排查

风雪同学_3534

风雪同学_3534

发布时间:2026-10-25 09:26:43

|

151人浏览过

|

来源于php中文网

原创

PayFast API 签名生成详解:Python 实现与常见错误排查

本文详细解析 payfast 支付网关中 md5 签名的正确生成方法,涵盖参数排序、大小写规范、url 编码细节及调试技巧,帮助 python 开发者避免 “signature does not match” 错误。

本文详细解析 payfast 支付网关中 md5 签名的正确生成方法,涵盖参数排序、大小写规范、url 编码细节及调试技巧,帮助 python 开发者避免 “signature does not match” 错误。

在集成 PayFast 支付 API 时,签名(signature)验证失败是开发者最常遇到的问题之一,典型报错为 400 signature: Generated signature does not match submitted signature。该错误并非源于加密算法本身,而几乎总是由参数拼接字符串(param string)与官方要求不一致导致——哪怕一个空格、大小写偏差或排序错位都会使 MD5 哈希值完全不同。

✅ 关键规范回顾(依据 PayFast 官方文档)

PayFast 要求签名生成严格遵循以下规则:

  • 参数必须按固定顺序排列(非字典序!),顺序为:
    merchant_id, merchant_key, return_url, cancel_url, notify_url, name_first, name_last, email_address, email_confirmation, cell_number, amount, item_name, item_description, shipping_fee, payment_method, custom_int1, custom_int2, custom_int3, custom_int4, custom_int5, custom_str1, custom_str2, custom_str3, custom_str4, custom_str5, passphrase
  • 所有键(key)和值(value)必须转为大写(注意:passphrase 是唯一小写键名,但其值仍需大写编码);
  • URL 编码必须使用 urllib.parse.quote_plus(),且编码后全部转为大写字母(如 %3A → %3A 不变,但 ` →+,é→%C3%89`);
  • 空值参数必须完全排除(不能传 None、空字符串或 "");
  • PASSPHRASE 字段名必须全大写,且仅在拼接末尾追加一次(即使原始数据中已含);
  • 最终字符串不含任何前导/尾随空格或换行符。

⚠️ 原代码中的核心问题分析

你提供的实现存在多个隐性偏差:

Secure Python Code Sandbox
Secure Python Code Sandbox

安全 Python 代码沙箱:在隔离的沙箱中执行任意 Python 代码,预装 requests、NumPy、pandas 库。返回 stdout、stderr。

下载
  1. 参数顺序未强制固定:dict.items() 在 Python 3.7+ 虽保持插入序,但若构造字典时顺序错误,或使用 sorted() 等操作,极易出错;
  2. PASSPHRASE 键名误写为 PASSPHRASE(全大写)但文档明确要求字段名为小写 passphrase —— 注意:这是唯一键名小写、值大写编码的特例;
  3. urllib.parse.quote_plus(...).upper() 存在风险:%xx 编码本身已是大写十六进制,重复 .upper() 无害,但若原始值含 Unicode 字符(如 é → %C3%89),.upper() 对 % 符号无效,逻辑上冗余且易误导;
  4. 未对 passphrase 值做 URL 编码后再大写:应与其它值一致处理。

✅ 推荐修正实现(生产就绪版)

import hashlib
import urllib.parse

def generate_payfast_signature(data: dict, passphrase: str) -> str:
    """
    严格按照 PayFast 文档生成 MD5 签名。
    参数顺序、大小写、编码方式均与官方要求 100% 一致。
    """
    # 固定参数顺序(关键!)
    required_keys = [
        "merchant_id", "merchant_key", "return_url", "cancel_url", "notify_url",
        "name_first", "name_last", "email_address", "email_confirmation",
        "cell_number", "amount", "item_name", "item_description",
        "shipping_fee", "payment_method", "custom_int1", "custom_int2",
        "custom_int3", "custom_int4", "custom_int5", "custom_str1",
        "custom_str2", "custom_str3", "custom_str4", "custom_str5"
    ]

    # 构建有序参数列表(仅包含非空值)
    encoded_pairs = []
    for key in required_keys:
        if key in data and data[key] not in (None, "", b""):
            value = str(data[key]).strip()
            # URL encode + 转大写(安全:quote_plus 已返回大写 %XX)
            encoded_value = urllib.parse.quote_plus(value)
            encoded_pairs.append(f"{key.upper()}={encoded_value}")

    # 追加 passphrase(注意:key 小写,value 同样需编码+大写)
    if passphrase:
        encoded_passphrase = urllib.parse.quote_plus(str(passphrase))
        encoded_pairs.append(f"passphrase={encoded_passphrase}")

    # 拼接最终字符串(无空格,无换行)
    param_string = "&".join(encoded_pairs)

    # 调试建议:打印前检查是否与 PayFast 示例完全一致
    # print("Param string for hashing:", repr(param_string))

    # 生成 MD5 签名
    signature = hashlib.md5(param_string.encode("utf-8")).hexdigest()
    return signature

# 使用示例
payload = {
    "merchant_id": "11111111",
    "merchant_key": "UAAAAAAAAAAHA",
    "return_url": "https://example.com/dev/payfast-redirect",
    "cancel_url": "https://example.com/dev/payfast-redirect?status=failed",
    "notify_url": "https://example.com/dev/payments/payfast-notify",
    "email_address": "john.doe@gmail.com",
    "amount": "300",
    "item_name": "COOL&THING",
    "item_description": "BLAH&BLAH&BLAH"
}
sig = generate_payfast_signature(payload, "PHRASEFROMSANDBOX")
print("✅ Final signature:", sig)

? 调试黄金法则

  • 逐字符比对:将生成的 param_string 与 PayFast 沙箱返回的“expected string”(如有)或文档示例逐字符对比(推荐用 diffchecker.com);
  • 禁用 .upper():urllib.parse.quote_plus() 输出默认为大写 %XX,无需额外 .upper();保留它可能掩盖编码逻辑错误;
  • 沙箱环境验证:PayFast 提供 Signature Validator Tool(需登录),可上传你的参数和密钥,实时校验;
  • 日志记录明文串:上线前务必记录 param_string(脱敏后),它是排错唯一可信依据。

✅ 总结

PayFast 签名失败极少因哈希算法错误,绝大多数源于字符串构造阶段的微小偏差。坚持三点即可大幅降低故障率:
① 硬编码参数顺序(勿依赖字典遍历);
② passphrase 字段名小写、值编码、不参与主循环;
③ 全程使用 urllib.parse.quote_plus(),避免手动 .upper() 干预编码结果。

遵循本教程实现,你将得到与 PayFast 服务端完全一致的签名,顺利通过验证。

立即学习“Python免费学习笔记(深入)”;

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

1811

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

4744

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

1749

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

28257

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3407

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3407

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

1203

2023.08.11

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

616

2023.08.10

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

40

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Uvicorn官方安装与入门手册
Uvicorn官方安装与入门手册

共0课时 | 0人学习

Python uv官方项目管理指南
Python uv官方项目管理指南

共0课时 | 0人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn