• 注册
  • 查看作者
  • 宫论项目开发记录

    记录2023年项目进度周期。

    刷新置顶
  • 2
  • 454
  • 0
  • 9.84w
  • 小小乐小可鸭鸭

    请登录之后再进行评论

    登录
  • 0
    小小乐lv.2实名用户
    2024年7月26日
    1、当用户成功完成人脸识别之后,系统会触发xc_face_ok_hook钩子来执行相应的业务处理逻辑。如果人脸识别的当前场景为“retrieve”,则意味着用户此次操作的目的是为找回或重置账户。为确保操作的安全性和权限控制,该钩子会生成一个专用的token令牌。此令牌的生成方式是基于当前时间戳,通过MD5算法进行加密处理,确保其唯一性和不可预测性。生成的令牌将被赋予一个2小时的有效期限,以防止潜在的安全风险或滥用。用户进行账户资料重置操作期间,该令牌将作为鉴权使用的关键凭据,确保只有合法持有该令牌的请求才能对账户信息进行更改。这种机制不仅提升了操作的安全性,还提高了系统的整体可靠性和用户体验。
    2、为了确保token令牌在传输和使用过程中不会被非法篡改或者伪造,现有人脸识别核验生成令牌的方式进行了全面优化和安全提升。首先,令牌标识使用MD5加密算法进行安全加密处理,具体实现为对'retrieve:' . $id进行MD5加密,从而生成唯一且加密的标识字符,确保其在传输过程中的完整性和安全性。其次,令牌的内容被设计为一个复杂且多层的数组结构,内部包含了多个关键信息元素:当前用户的相关信息、用户的IP地址、设备指纹信息、用户代理(User Agent)参数、人脸识别ID主键以及令牌生成的时间记录。这种多维度的信息集合不仅提升了令牌的安全性,还确保了来源的唯一性和不可篡改性。
    3、服务端新增了一个名为 xc_account_reset_hook() 的账户重置钩子,这个钩子需要接收一个参数,即user_id(操作对象的唯一标识)。当用户执行找回账户、重置账户、申诉账户等相关操作时,账户将会被重置。在这个重置过程中,涉及到对大量账户资料的处理。由于这些操作场景非常多样化,因此我们需要封装一个统一的钩子来进行业务逻辑的集中处理和管理。这个钩子xc_account_reset()将返回一个标准的数组结构,其中code字段与处理结果相关联:code值为0时表示处理成功,code值为1时表示处理失败;msg字段用于提供失败情况下的错误原因和详细信息。
    4、xc_binding_phone_ok_hook:对于手机号换绑操作的钩子进行了全面优化,新增了一个重要变量:user_id,该变量表示操作对象的用户,默认为空。当user_id为空时,将自动读取当前操作用户的user_id;当user_id不为空时,则按照指定的用户进行操作。变量type表示处理方式,此次除了rebind(换绑)和bind(首次绑定)之外,又增加了一个新的处理场景:unbind(解绑)。这样,用户在解绑手机号时,也会符合钩子的触发机制。为了确保业务的一致性,尤其是缓存设计的一致性,现在所有关于手机号的操作——无论是更换、绑定还是解绑——都必须经过此钩子进行处理。
    5、xc_binding_email_ok_hook:邮箱换绑操作钩子进行了全面优化处理,与手机号换绑操作的优化一样,系统新增了一个名为user_id的操作对象变量。在这一改进中,如果操作过程中该变量不存在,则系统会自动读取当前正在进行操作的用户信息。优化还进一步拓展了type处理场景,新增加了一种解绑(unbind)操作类型,专门处理用户邮箱的移除请求。在收到解绑请求时,系统将会通过调用wp_update_user方法,将用户绑定的邮箱地址从其账户信息中彻底移除。
    6、账户重置钩子xc_account_reset_hook,触发时会通过xc_binding_email_ok_hook和xc_binding_phone_ok_hook两个方法,将用户的手机号绑定和邮箱绑定资料清空处理。账户需要重置,说明用户的手机号和邮件都已经不可用了。因此,必须将现有绑定信息移除,以便用户可以重新进行绑定操作。需要注意的是,重置账户是一个非常敏感的操作,必须特别谨慎地进行处理。
    7、在进行用户账户重置操作时,系统会主动移除用户以下两个关键字段,以确保账户的正常使用和登录顺畅。首先,移除字段“login_security”,该字段用于存储用户的登录配置信息;其次,移除字段“login_address_security”,此字段包含用户的登录地址配置。这两个字段包含用户设置的安全措施,比如禁止密码登录、限制地区登录。
    8、修复用户注册后,人脸识别免费额度没有发放给用户的问题。由于每次调用人脸识别SDK都需要支付费用,平台不可能无限制地为用户提供补贴。为了解决这个问题,通过后台的xc_face_free_number字段设置了每个用户在注册时的免费使用次数,上限为X次,超出部分则需要用户自行购买资源包。正确的执行流程应为:在用户注册时,系统会检测是否存在可用的免费额度,如果存在,则在注册成功时将该免费额度发放给用户。用户在进行人脸识别操作时,系统会自动抵扣免费额度。而之前的业务逻辑中存在语法错误,导致免费额度未能正确发放给用户。现已针对该问题进行了修正处理,确保用户在注册后可以顺利获得并使用对应的免费额度。
    9、当用户尝试通过人脸识别找回账户时,系统首先会通过is_account_status函数来读取用户的账户状态信息。如果系统返回的code值为1,则表示该用户的账户当前处于异常状态。在这种情况下,系统会进一步对具体的账户状态进行判断。如果用户的账户状态为banned(被封禁),系统将返回消息:【'你的帐号【' . avatar['nickname_type'] . '】已被限制登录,封禁时间:' .avatar[ ′ nickname t ​ ype ′ ]. ′ 】已被限制登录,封禁时间: ′ .ban_time . '<br>封禁原因:' . $account_status['reason']】。该消息明确告知用户其账户已被限制登录的原因及具体封禁时间。如果用户的账户状态为deleted(已注销),系统将返回消息:【该帐号已被注销,无法找回】。此功能的设计目的是为了防止那些已经被平台注销或拉黑的用户通过人脸识别功能来重置账户并重新获得访问权限,从而确保平台的安全和秩序。
    10、在人脸识别成功后,如果当前的场景为retrieve(即进行账户找回操作),将会触发名为xc_account_reset_hook的方法,执行账户重置过程。账户重置完成后,系统会返回一组详细的信息到前端界面。这些信息包括:code字段,其值为0,表示操作成功;token字段,包含了具体的重置令牌信息,确保安全的账户重置过程;msg字段,值为“刷脸成功:前往重置账户”,用于提示用户刷脸操作已成功,可以进行下一步的账户重置;type字段,明确指出当前操作的人脸识别场景,确保信息的准确传达;id字段,包含了人脸数据表的主键ID,用于唯一标识具体的生物识别记录;最后是table_name字段,指明了存储相关数据的数据表名称。
    11、新增页面:【/global/account_reset.php】账户重置页面。此页面的访问权限依赖于传递的TOKEN令牌,必须通过校验TOKEN令牌才能成功访问该页面。若请求中缺失该TOKEN令牌参数,将返回错误信息:非法请求。页面的唯一标识为:account_reset。当用户通过人脸识别完成身份验证后,服务端会生成并发放一个专属的token令牌并传递给前端。前端接收到这个token令牌后,利用该令牌进行鉴权访问此账户重置页面。在这个页面上,用户可以安全地设置新的账户密码,从而完成整个账户重置的过程。
    12、账户重置页面已经通过require_once引入了ajax_page.php脚本。为了防止出现非法请求或重复请求,在进入特定页面时会通过get_redis_meta函数来解析token令牌,并从中提取user_id、id等关键字段内容。然后,这些关键字段的信息会以自定义属性的形式写入到页面的page-content元素中,方便后续前端代码进行调用和处理。如果获取这些关键字段内容的操作失败(比如令牌无效或者令牌过期),则会通过xc_empty函数在页面中显著地显示出【非法请求】字样,以警示用户并防止进一步的操作,从而确保系统的安全性。
    13、在账户重置页面新增一个提示框,标题为:账户重置说明。提示框的内容涵盖四个重要信息【1、账户当前已关联的【手机号/邮箱】已完成解绑操作。2、账户的登录配置文件已重新设置,所有登录限制已被取消。3、密码修改成功后,账户便可以使用新密码直接登录。4、完成重置操作后,建议及时绑定新的手机号或邮箱。】
  • 0
    小小乐lv.2实名用户
    2024年7月25日
    1、无论在什么场景下,在完成基础拦截请求后,系统会通过get_user_meta函数来读取用户字段face_number。如果该字段为空或者次数小于1,则会触发保护机制。此时系统将返回一个带有code=1和msg=实名认证需先支付实名费用的响应,提醒用户需要先进行实名认证付款操作,再继续进行认证。需要特别注意的是,如果当前用户是游客,系统必须提前赋值user_id,以防止因缺失用户身份信息而始终返回欠费提示。
    2、如果人脸识别次数包不足,不需要通过前端二次进行支付业务关联,而是直接通过add_payment_order_hook来创建付款订单。在尝试创建付款订单时,若遇到失败情况,则应返回相应的错误提示,以便及时处理和排查问题。成功创建订单后,将返回一个包含支付令牌的响应【jump:payment】,并且前端会直接跳转至付款页面以完成支付流程,从而简化操作步骤,提高用户体验,确保支付环节的顺畅进行。
    3、修复与人脸核验相关的问题,当用户在找回账户页面触发 xc_hooke_real_personal 事件时,页面会错误地后退至登录页面。此错误的根源在于前端处理【核验请求】时,误将 xc.is_login 逻辑设置为通用规则。这种处理方式导致了一个问题,即在找回账户的游客模式下,系统也会强制用户重新登录。因此,需要调整逻辑,使其在游客模式下不会触发重新登录流程,从而优化用户体验,确保找回账户功能的正常运行。
    4、xc_hook_Framework_back 重大BUG 修复。这个方法专门用于监听并接管【Framework7的后退事件】。在这个钩子中有一个监听行为,通过使用 :last 选择器来获取当前页面的元素,并对这些元素进行相应的业务逻辑处理。例如,它会判断用户是否已经关闭了某些菜单项。如果用户未关闭这些菜单,则会阻止用户退出。然而,之前获取当前页面元素的方法存在一些问题,导致在某些页面上无法正确获取元素,从而引发监听元素不存在的情况,进而使得预期的业务行为未能被触发。此次修复解决了上述问题,保证了监听行为的正常运行。
    5、xc_face_check_hook钩子优化:在处理账户找回请求时,该钩子将执行一系列优化步骤。首先,在获取到用户的身份证数据后,系统将提取身份证上的姓名和身份证号码,即name和code。接着,系统会对这些信息进行解密操作,确保数据的合法性和安全性。随后,系统会将解密后的身份证姓名与号码同用户在表单中输入的信息进行逐一对比。如果发现身份证上记录的姓名或号码与用户输入的信息有任何不匹配,系统将立即返回【身份证信息不匹配,无法完成验证】的提示信息。
    6、修复重复进入宫论统一支付页面时出现的付款截止倒计时叠加问题。当前情况是,每次重新进入支付页面,页面的计时器会自动增加1,而不是在用户后退时自动注销旧的计时器。为了解决这个问题,需要通过back行为钩子来监听用户的后退事件。一旦检测到页面存在计时器,系统将立即将其暂停并移除。
    7、支付成功回调业务配置:当支付类型为【face_number】时,系统将首先读取支付用户的face_number字段。如果该字段为空或者不存在,则会将其初始化为0。这一步确保在后续处理过程中,face_number字段有一个合理的初始值。然后,系统会调用update_user_meta函数来更新用户的meta数据,此时会增加用户的face_number值。通过这个过程,系统实现对用户人脸识别额度的充值,确保用户可以继续使用基于人脸识别的支付功能。
    8、在APP端登录页出现的错误提示【Undefined variable $xc_login_protocol in】问题进行了修复。具体情况是:在华为手机上,APP默认不允许用户协议被预先勾选,需要用户主动点击复选框以示同意,而在其他设备上,用户协议则是默认勾选的。造成这一问题的关键在于变量xc_login_protocol的使用。这个变量用于确定是否需要默认勾选用户协议,但它仅在非华为设备上才会被创建,因此在华为手机上就会出现该变量未定义的情况,从而引发错误提示。为了解决这个问题,采用了三元运算符进行处理,即在变量不存在的情况下,将其赋值为空字符串‘’,从而避免了因变量未定义而带来的错误。这种处理方式不仅能确保在不同设备上的用户体验一致性,还能够有效防止因变量未定义导致的其他潜在问题,从而提升代码的健壮性和稳定性。
    9、修复了在支付宝订单支付成功后无法正确回调的问题。经过详细的栈追踪和分析,发现回调日志并没有被触发,这意味着支付宝的异步通知没有成功接收到。进一步排查过程中,发现问题的根源在于异步回调文件访问过程中存在一个致命性的错误返回,导致系统未能正确接收和处理支付宝的回调信息。经过认真修正和多次测试,目前该问题已彻底解决,支付宝订单的异步回调功能已恢复正常,能够顺利接收并处理支付成功后的通知。
    10、为了确保用户在支付成功后能够及时收到通知,采取了websocket方式来通知用户,然而,这种通知依赖于user_id来下发,这就带来了一个潜在的问题,即如果用户处于未登录状态(在某些支付场景下,游客用户也是可以进行支付的),那么支付成功后,页面将无法收到任何通知,从而无法进行交互。为了进一步解决这个问题,设计了一个机制:能够同步接收支付结果的付款渠道(如APP内付款、微信公众号内支付)都会在支付成功后首先判断用户状态。如果发现用户未登录,系统将自动触发一个名为xc_hook_payment_success的事件。这个事件的触发能够保证即便是在未登录的情况下,用户也能够及时接收到支付成功的相关反馈,从而优化支付体验并确保操作的一致性和流畅度。
    11、(人脸识别资源包)在用户成功完成付款后,会触发【xc_hook_payment_success】前端回调钩子,实现了对付款成功事件的监听。付款成功后,用户界面将通过此钩子进行相应的页面交互操作,确保用户体验连贯顺畅。当用户购买人脸识别资源包成功,不仅会执行通用操作规则,还会触发特定的页面行为。系统会在延迟两秒之后自动执行页面后退操作,将用户带回到人脸识别认证页面,使用户能够继续进行下一步的认证操作。
    12、宫论第二个支付场景:【face_number】已顺利完成接入。这一成就得益于采用了统一支付架构,使得接入过程变得极为高效快捷。在这一过程中,开发人员无需过多关注具体的支付流程和方法,只需要专注于支付回调的业务处理即可。未来的支付业务同样方便,只需在后台新增支付场景,并配好相应的参数信息。接下来,对付款成功的回调事件进行单独处理,就能顺利完成一次新的支付场景对接。
    13、人脸识别核验成功钩子xc_face_ok_hook进行重构优化,增加通用业务回调和场景业务回调。通用规则:首先,将xc_face数据表进行状态回调,将其标记为OK,这一操作代表本次人脸识别已顺利完成,并且确保数据的状态在整个处理过程中保持一致性,从而进一步提升系统的健壮性和可靠性。场景规则:针对不同的支付场景以及业务需求进行个性化处理。比如在实名认证场景下,需要创建一个独立的实名认证记录表,将用户的相关认证信息详实地写入其中,这不仅确保了数据的完整性和可追溯性,还可以为以后的审计和数据分析提供有力的支持。同时,还需同步更新用户元数据中的对应标识字段,以反映最新的认证状态,确保数据的一致性和及时性,从而完成整个认证处理工作。由于不同的人脸识别场景所涉及的业务逻辑差异较大,因此有必要在设计中做出明确的区分处理,让人脸识别回调功能能够灵活适应不同的业务需求。
  • 0
    小小乐lv.2实名用户
    2024年7月24日
    1、在人脸找回账户页面中,现有机制会脱敏显示身份证信息,这可能导致一定的隐私泄露风险。现阶段,该页面仅需传递ID变量即可发起SQL查询,存在隐私安全隐患。因此,为提升安全性,对该页面的访问机制进行调整。即除了需要传递ID,还需传递code(加密的身份证号码)。在执行SQL查询时,将通过这两个字段进行匹配验证,以确保只有在正确传递这两个参数的情况下,才能查看脱敏后的信息。
    2、后台新增字段:人脸找回账户备注信息字段(xc_real_retrieve_account_desc),该字段支持短代码和HTML格式,可以填写一些找回账户的详细说明,例如付款流程和重置账户的机制。当用户通过找回功能进行人脸实名操作时,页面将显示这部分内容,以便用户了解相关操作步骤和注意事项。这一功能的引入旨在提升用户体验,确保用户在找回账户时能够获得清晰、详细的指导,从而顺利完成账户找回操作。
    3、在后台系统中新增了一项协议,名为【实名人脸找回账户协议】,其唯一标识为:face_retrieve_account。协议的具体地址目前尚待补充,现已用占位符#填空。在personal_recovery(人脸找回账户)页面中,系统将通过do_shortcode方法来嵌入和展示该协议的详细内容。用户在发起下一步操作之前,必须阅读并同意此协议的全部条款,否则将无法继续进行账户找回流程。
    4、修复【个人实名认证页面】和【人脸找回账户页面】在鉴权失败时不输出相应错误提示的问题。目前,这两个页面在鉴权失败时执行了 xc_empty 函数,但由于未使用 echo,导致错误提示信息无法显示。为解决这一问题,需要在函数调用处添加 echo 以确保错误提示能够正确显示。此外,这两个页面还集成了【equire_once xc_local_link('ajax_page.php')】页面访问事件拦截功能,如果用户进行非法请求,将会触发规则拦截机制,阻止非法访问行为。
    5、xc_hooke_real_personal(个人实名认证钩子,增加一个变量,type:默认值为personal)。人脸识别流程非常复杂,且在后期可能会有较大的变动。为了避免在每个场景下重新执行完整的流程,减少工作量,也为便于业务维护,需要采用更加灵活的处理方式。具体来说,在执行人脸识别时,通过type变量来确定业务场景,根据不同的场景采取相应的事件拦截措施。这样可以实现一个通用规则与各个场景规则的配合,确保不同场景下能够调用合适的处理逻辑。
    6、账户找回业务中,触发的人脸识别请求标识定义为:retrieve。在进行前后端交互时,都需要通过这个标识来区分具体业务。而原有的人脸实名认证业务标识将变更为【personal】。由于人脸识别SDK涉及的业务范围非常广泛,而且后续会有更多的集成需求,因此在此次进行找回密码和重置功能开发时,必须做好业务分离工作,确保在以后的业务场景中,可以高效、一步到位地完成接入。
    7、前端人脸识别钩子【xc_hooke_real_personal】现已支持“retrieve”功能。当用户发起账户找回请求时,前端系统将执行以下拦截验证步骤。首先,通过xc_is_protocol核实用户是否已勾选找回协议。如果用户未勾选相应协议,则会弹出提示信息【请查阅并勾选页面相关协议】。接着,系统会使用xc.is_login方法验证用户的登录状态。如果用户已登录,系统将提示【处理失败:找回功能仅限未登录用户】。最后,系统会检测当前页面是否包含元素page-content.personal_recovery。如果页面未包含此元素,系统将提示【处理失败:非法请求】。
    8、在通用人脸识别功能中,当钩子被触发时,系统会首先初始化一个名为real的对象,并使用let关键字将其声明为局部作用域变量。这个对象包含以下通用参数:real.name(身份证姓名)、real.code(身份证号码)、real.type(人脸识别场景)。其中,real.name和real.code是通过页面中的表单元素来获取的,具体提取的元素会根据不同的人脸识别场景有所区别。在获取这些参数后,系统会使用正则表达式对参数进行有效性验证,以确保输入的数据没有包含非法字符。
    9、人脸找回账户页面新增了两个字自定义属性:id 和 idcard。这两个属性通过 GET 请求中的变量进行提取。在前端发起人脸识别函数请求时,系统会将这两个参数封装并提取到 real 对象中。如果这些参数中有任何一个缺失,系统将返回错误提示,以确保参数的完整性。在服务端开始执行人脸识别操作时,首先需要对这两个参数变量进行验证,确保它们的正确性和有效性。
    10、服务端在进行人脸识别操作时,现已引入基于场景的拦截策略,该策略允许针对不同的人脸识别场景实施个性化的处理措施。在通用规则的基础上,每个具体的识别场景都可以设定独立的拦截和返回策略。例如,在个人实名认证(personal)场景下,系统会特别检测后端字段[xc_real_personal]。如果该字段未开启,系统将会返回提示信息【管理员已关闭了【人脸识别认证】接口】,从而确保在未经授权的情况下,相关接口无法被调用。
    11、在最新的人脸识别配置页面中,新增了一个重要字段:xc_real_retrieve_account(是否开启人脸找回账户)。这一功能允许用户通过人脸识别接口找回并重置账户。如果该选项被关闭,则用户将无法使用人脸识别功能来找回其账户。这项设置作为一个全局开关,确保在前端和服务端都能得到充分的验证和拦截。在用户提交找回账户申请时,前端会首先对该选项进行拦截检查,确保不允许通过关闭此选项的用户提交找回账户的请求。同时,服务端在收到请求后也会进行严格的拦截检测,进一步防止任何非法的提交行为。
    12、服务端已完成账户找回功能中的人脸识别基础拦截规则。除了通用拦截规则以外,进行账户找回处理请求时,还会额外进行以下检测:首先,查询【xc_real_retrieve_account】字段的状态,如果该字段未开启,则立即返回错误提示【认证失败:管理员关闭了人脸找回账户功能】。其次,检测xc_is_login接口是否已返回UID,如果已返回UID则提示用户【认证失败:找回账户前请先退出登录】。第三步,构建wpdb查询,检测提交的身份证号和验证码是否匹配数据库中的记录。如果查询结果不存在匹配的记录,则返回错误提示【认证失败:身份证信息不匹配】。若上述所有检测均通过,则会将user_id变量标记为实名用户,此标记将在后续支付业务处理中使用。
    13、在redis配置页面的安全拦截检测配置组中,新增了一个用于拦截人脸识别接口请求(idcard_face)的拦截器。该拦截器通过IP地址作为标识进行拦截。具体配置为:当一个用户在五分钟内进行人脸识别请求的次数达到或超过10次时,将触发拦截机制,进入主锁状态,主锁持续时间为300秒(即五分钟)。如果在主锁状态过后,用户仍然在短时间内频繁请求,也会触发副锁机制,副锁持续时间为5秒。使用这项配置后,每次用户进行人脸识别请求时,会触发redis_security_check检测。为了确保系统安全且避免滥用,每次请求的最短间隔时间为5秒,且在五分钟时间内最多只能进行10次请求。超过这一限制后,系统将自动拦截用户请求,并向用户发送超速提醒,提醒内容中会包含具体的时间信息,帮助用户了解下次可以正常进行请求的时间。

  • 0
    小小乐lv.2实名用户
    2024年7月23日
    1、对于xc_login_hook登录钩子的优化,如果用户处于微信端,则不再触发异地报警提醒。微信登录的过程需要获取code进行鉴权,这使得用户的微信APP必须处于在线状态,因此可以认定这种登录场景是安全可靠的。为了进一步优化用户体验和提高系统效率,在执行安全风控检测时,需要跳过对微信端的验证,从而减少不必要的安全提醒。具体实现方法是通过使用函数xc_is_weixin()来判断用户是否处于微信端,通过这种方式对微信端的拦截检测直接放行,从而精简安全流程。
    2、在登录钩子执行业务逻辑的过程中,如果用户开启了异地登录提醒功能,但用户的设备环境是【微信浏览器、微信小程序】,那么系统会跳过安全检测流程,不会读取当前设备的IP地址来执行省份地区拦截处理。这种情况下,即使启用了异地登录提醒功能,系统将在以下几种特定情况下放宽安全措施:首先,如果用户并未开启该功能,系统无需执行相关检查;其次,当用户使用短信或手机号作为登录方式时,系统也会跳过IP地址的读取和省份地区的拦截处理;最后,当用户以微信鉴权登录的方式进行登录时,同样不会触发地区拦截机制。
    3、修复并解决【忘记找回】功能中下一步操作时出现的返回异常问题【Uncaught TypeError: preg_match(): Argument #2 (subject) must be of type string, array given in】。该错误是由于在调用xc_phone_regular(subject)mustbeoftypestring,arraygivenin】。该错误是由于在调用xc_phone_regular(phone)方法验证手机号时,错误地传递了不可识别的字符类型(数组),导致正则匹配出现错误并返回异常信息。经过详细的检查与调试,现已对代码进行了修复处理,确保在验证手机号时能够正确传递字符串类型参数,避免此类错误的再次发生。
    4、xc_maskStringInRange 脱敏处理字符串输出函数进行两处优化。首先,如果需要处理的字符串意外传递为数组,则函数会直接返回 false,从而阻止后续的脱敏处理。这是为了确保输入类型的正确性,避免处理非字符串数据导致的不必要错误。其次,函数在接受到 start 初始位置变量时,将不会进行 xc_phone_regular 和 xc_idcard_regular 两个自动匹配验证,这样能够防止字符星号偏移的问题,确保脱敏处理的精确性和输出结果的一致性。通过这两个优化,函数在处理数据时将更具鲁棒性和准确性,避免了因输入异常或不必要的自动匹配造成的潜在问题。
    5、找回账户页面的流程以前是通过传递固定字段值来调用xc_is_login_idcard方法,从而获取用户的【身份证号,姓名】信息。这种方式已被重构,导致尽管用户账户已认证成功,也无法正确获取与之关联的身份证信息。重构后的方法大大简化了获取身份证信息的流程,不再需要传递特定的字段值。当匹配查找成功时,系统会直接返回整个实名认证数据表的字段作为响应内容。只需要通过数组方式输出对应的内容即可完成相关信息的获取与展示。
    6、用户通过找回账户功能查找关联绑定账户时,如果发现关联账户绑定了身份证信息(通过函数xc_is_login_idcard验证),系统将采用xc_decrypt方法对该信息进行解密。具体解密字段包括【name:姓名】和【code:身份证号码】,成功解密之后,需要使用xc_maskStringInRange方法对这些信息进行脱敏处理,再进行输出。需要注意的是,出于安全隐私设计的考虑,用户的实名信息在存储过程中均会采用加密技术。如果在未进行解密和脱敏处理的情况下直接调用输出,这些信息将显示为加密字符串以确保用户隐私不被泄露。
    7、xc_find_account_hook忘记账户查找接口优化,通过身份证号码查找绑定关联账户的时候,始终返回查询失败:该身份证未绑定任何账户。该错误是由于隐私安全保护,数据库存储的身份证号码是加密过的,直接查询是不可能匹配成功的,正确的处理方式,通过xc_is_idcard_user发起查询请求时,需要对传递的字符串进行加密处理,确保值能匹配成功。
    8、xc_is_idcard_user 方法用于检查给定的身份证号码是否存在于数据库中,并返回与之关联的用户ID。原始实现中存在一个致命的错误:在构造查询匹配 SQL 时,程序错误地使用了已更新的状态字段,这导致查询始终无法匹配成功。具体来说,程序使用了已经废弃的 state 字段,而正确的字段名称应该是 status。这导致无论怎样输入身份证号码,方法都无法正确匹配并获取相关用户信息。正确的解决方案是修改查询语句,使其使用正确的 status 字段进行状态匹配。
    9、修复找回账户页面出现【Undefined variable $link in】报错的问题。该问题的根源在于link变量决定了页面跳转的行为,但由于在实名认证过程中页面的跳转是通过onclick事件来完成的,因此无法执行link变量的初始化阶段。这种初始化缺失导致了Undefined错误的发生。为了保证link变量能够被正确初始化并避免报错,需要调整代码的逻辑。
    10、新增前端事件:xc_hook_idcard_face_verify()。用于申诉找回账户(身份证人脸识别)验证,钩子执行后,会执行以下动作。1、检测用户页面是否包含page-content.retrieve_list元素,如果不存在则视为非法请求。2、从当前BTN按钮中提取【$idcard['id']:实名认证数据表主键ID、$idcard['code']:加密后的身份证号码】。然后等待下一步操作。
    11、新增页面【global/real/personal_recovery.php】,该页面旨在通过实名认证(人脸识别)的方式帮助用户找回自己的账户。页面的唯一标识为:personal_recovery,允许游客访问,不设置登录拦截限制。用户可以在此页面提交相应的身份证信息,完成初步验证后,将进入人脸识别操作,以进一步确认其身份。为了确保验证过程的顺利进行,访问该页面时,必须通过GET参数传递用户的ID信息。页面在接收到ID参数后,需要获取并显示与人脸识别对象相关的具体信息,从而确保身份验证的准确性和可靠性。
    12、人脸识别找回账户页面:首先,该页面会通过$_GET['id']参数提取用户的唯一ID主键。接着,利用WordPress的数据库对象wpdb,构建并执行查询语句以检索数据表中是否存在匹配的记录。如果未能找到相关记录,则页面将直接返回【非法请求】的提示信息。若成功找到匹配的记录,则在页面上生成两个输入表单域:real_face_name_input(用于输入姓名)和id_card_number_input(用于输入身份证号码)。用户需要在这些表单中输入相应的个人信息以找回账户。提交后,系统将依据所提供的身份证信息尝试发起人脸识别验证,确保输入信息和记录中的数据相符,从而验证用户身份。
    13、用户在尝试通过人脸识别找回账户时,页面标题将显示为【人脸核验 - 找回账户】。在待输入的表单中,系统会解密并脱敏显示用户的部分实名信息,例如【姓名:张***、身份证号码:362***********123X】。这样可以辅助用户输入正确的实名信息,以便进行下一步操作,即调用实名认证SDK,完成实人认证请求。
  • 0
    小小乐lv.2实名用户
    2024年7月22日
    1、宫论统一支付业务,已集成微信公众号支付,如果用户在微信环境,则只能选择【余额支付+微信公众号支付】。后端会通过UA来识别确认设备环境,然后调用统一支付SDK来发起支付请求。如果成功取得payment数据包,那么将返回前端,执行【xc_wx_jsapi_pay(payment)】函数,通过微信js-sdk拉起微信支付页面,如果中途出现错误会通过try来捕获异常,并返回页面提示信息。
    2、公众号支付提示用语优化不再通过xc_msg返回错误提示,而是直接使用【weui】组件进行提示。具体实现方法是,在用户完成支付后,直接调用$.toast(result.msg)函数,这样用户就能获得类似微信原生的提示体验。如果支付过程中出现失败情况,例如支付失败或用户中途退出,则会使用forbidden选项,更改提示中的图标,以直观地向用户传达支付失败的信息。通过这种方式,支付提示将更加统一和友好,提高用户体验。
    3、宫论统一支付钩子:目前已支持以下几种支付场景。1、APP支付:支持支付宝原生SDK支付,让用户能够同步获得支付结果,充分体验APP原生的支付流程。2、H5支付宝支付:针对浏览器端访问的用户,可以通过网页端完成支付请求,确保用户在不同设备上都有便捷的支付体验。3、微信H5支付:支持网页浏览器的用户使用H5形式完成支付请求,满足多种浏览器环境下的支付需求。4、微信jsapi(公众号)支付:为微信浏览器内的访客提供通过微信原生SDK进行支付的功能,简化支付流程,提高用户体验。5、余额支付:在账户余额充足的情况下,支持用户通过账户余额完成相关支付需求,提升支付的灵活性和便捷性。注:微信APP原生支付需要在应用上架后才能申请,该接口已封装,未来版本会集成该功能,以进一步丰富支付方式的选择。
    4、出于对支付回调的安全考虑,宫论所有的支付场景都不允许通过同步来执行回调结果通知,(即便APP、微信端支持同步返回结果,也不负责支付成功的事件的触发)。是否支付成功,页面的交互行为必须通过websocket消息来触发。无论是支付宝付款,还是微信付款,只要支付成功,都会通过异步接口来接收回调订单数据。只有异步接口成功捕获到付款订单信息,并核实完成付款。才会触发websocket消息,来告知用户已完成付款,并执行页面对应的处理。
    5、当WebSocket成功收到付款成功的通知后,将通过xc_hook_payment_success钩子执行以下两个动作:首先,如果当前环境不是H5,则会直接调用$.toast("付款成功")方法,弹出一个持续5秒钟的提示通知,告知用户付款成功。其次,如果用户此时正处于统一支付页面,将在原有页面交互逻辑的基础上,增加对付款倒计时的处理机制。这将通过clearInterval方法先行移除现有的倒计时,然后利用xc_hook_global_countdown方法清除倒计时数组的相关数据。最终,倒计时显示的数字会被更改为“success”,以明确告知用户付款已成功完成。
    6、新增支付成功回调接口:xc_payment_success_hook($id)。这个钩子将在用户支付成功后被触发,用以执行相应的业务变更逻辑。基于不同的业务场景,所需执行的业务逻辑也会有所差异。钩子的主要参数是订单的主键ID值(即支付订单数据表中的ID)。请注意,钩子本身不进行任何安全验证,因此在使用时务必要特别考虑到业务安全问题。
    7、对xc_payment_success_hook业务回调进行了优化处理。首先,该钩子不再被关联注册到程序核心库中,而是被挂载到callback.php文件中。此举确保钩子仅允许通过统一的支付回调机制来触发,避免了非法执行的可能性。此外,我们减少了对SQL的操作,钩子的ID参数变量改用payment,直接继承上级的支付订单数据表信息(以数组结构传递)。需要特别注意的是,针对每种支付场景,该钩子都需要进行业务适配。为了保证功能的稳定性和兼容性,每次更新后建议充分测试。
    8、支付成功业务回调钩子(xc_payment_success_hook)已经集成了处理【账户余额充值场景:recharge_money】等相关业务。当账户余额充值成功时,该回调钩子将会触发并执行xc_update_money_hook余额更新事件,从而将充值金额增加到账户余额中。余额标识为:recharge_money,描述备注为:账户余额充值。这一钩子的设计确保了在支付成功后,用户的账户余额能够被即时、准确地更新,提高了系统的可靠性和用户体验。
    9、余额更新钩子优化:当余额更新发生异常时,通常是由于【update_user_meta】函数返回异常。这种情况下,会触发日志写入机制,记录详细的错误信息。日志内容格式如下:[时间 - ' . date("Y-m-d H:i:s") . '] [余额场景 - (' . $shop_type . ':' . $shop_order . ')] [金额 - ' . $amount . '] [动作 - ' . $action . '] [备注 - ' . $text . '] [用户 - ' . $user_id . ']。通过这种方式,当余额更新失败时,可以通过日志进行溯源和跟进,确保问题能够及时发现和解决。
    10、余额充值支付场景至此已完成所有的业务对接。在这个过程中,用户需要通过余额充值页面,首先选择适合的支付方式(微信或支付宝)和希望充值的金额。当用户发起支付请求时,该请求会被标识为【update_money】并发送到服务端。服务端接收到请求后,会进行一系列的安全验证来确保交易的安全性。如果请求被验证为安全,系统将调用统一支付SDK。这一步根据支付场景的环境来处理数据包的交互工作。当服务端成功获取支付数据包后,相关数据会被返回给前端。前端则根据返回的数据,调用对应的支付SDK界面供用户完成支付。用户支付成功后,系统将通过异步环境解析支付请求数据,并进行必要的业务回调,最主要的是更新用户的余额数值。支付结果还会通过websocket回调到前端,以便执行相应的页面交互操作。需要特别注意的是,这整个流程是非常繁琐且复杂的,每一个步骤中都包含了许多事件的处理,确保整个支付过程顺利无误。
    11、新增第二个支付场景【face_number:人脸识别费用】,支付方式包括余额支付、支付宝付款和微信付款。考虑到实名认证相关场景,此支付场景在游客模式下也会触发,例如在进行人脸找回账户、人脸取消账户锁定等操作时都可以使用。因此,即使未注册的游客也能使用该支付功能。订单的关闭时间设定为10分钟,如果在10分钟内未完成付款,订单会自动取消。注:目前支付业务已基本完成开发,适配第二个支付场景。在对接过程中,更多的是细节补充完善,如果也能跑通,基本支付流程就算ok。
    12、为统一支付系统新增一项安全防护措施:如果用户选择使用余额支付方式,那么必须通过 xc_is_login 方法验证用户是否已登录。如果 xc_is_login 方法返回为空,则直接拒绝此次支付请求,并显示提示信息【支付失败:余额支付必须先登录】。这一安全措施旨在防止在游客模式下进行余额支付,从而避免用户资金泄露问题。此外,余额支付方式不允许通过参数传递 user_id,必须验证并确认当前操作用户的 UID 确实为本次余额支付的用户。
    13、进行人脸识别额度充值的时候,页面付款描述备注如下【进行人脸识别时,需要支付实名认证SDK的接口调用费用。只要完成了人脸识别对比,无论识别结果是否成功,系统都会扣除费用。然而,如果在过程中途退出或因接口故障导致识别失败,则不会产生计费。充值成功后,账户中的人脸识别验证次数将增加1次。该付费选项不支持退款,并且会在实际使用人脸识别SDK进行验证时自动扣除。】
  • 0
    小小乐lv.2实名用户
    2024年7月21日
    1、修复了在微信环境中.hideLoading()无法执行的问题。该事件是weui框架中的页面加载提示框关闭功能,但由于微信原生SDK的JavaScript和weui框架之间存在冲突,导致无法正常执行。这种冲突间接导致所有的提示指示器都无法被主动关闭,经过深入分析和调试,已成功解决此问题,确保.hideLoading()无法执行的问题。
    2、新增jquery-weui.min.js脚本文件:该文件集成了WEUI组件的相关JS事件,并通过wp_enqueue_script的方式进行注册和挂载工作。所有涉及到WEUI框架的JavaScript交互相关函数和脚本都被写入到这个函数库中,以便集中管理和调用。。为了优化网页的加载速度和用户体验,这个脚本文件采用异步延迟加载的方式,在页面完全加载后再执行初始化动作
    3、在weiixn.js(微信环境)脚本库中,新增了一个名为xc_wx_jsapi_pay的方法。这一方法需要传递一个包含支付信息的数组对象,即payment数组对象。该方法的主要功能是利用JSAPI(微信支付提供的前端JavaScript接口)来调起公众号支付,实现便捷支付体验。payment数组对象包含了由服务端(统一支付)返回的全部支付订单数据信息,这些信息包括appId、timeStamp、nonceStr、package、signType和paySign等关键支付参数
    4、xc_wx_jsapi_pay方法进行优化,新增第二个变量【callback】参数。callback 是一个回调函数,它将在微信支付请求 wx.invoke 的回调函数执行后被调用。这个回调函数接收一个单一的 result 对象作为参数,该对象包含两个属性:code: 一个数值,标识支付结果。0 代表支付成功,1 代表支付失败。msg: 一个字符串,包含支付结果的详细信息。
    5、当发起微信公众号支付请求时,为了确保在调用微信支付接口时不会出现预期之外的错误,在代码中增加了 try-catch 语句来捕获潜在的异常。这样做的目的是,当出现错误时,系统能够及时响应并返回相应的错误信息,保证应用的稳定性。在处理支付结果时,无论是正常处理还是异常处理,代码都会先检查 callback 是否为一个有效的函数,如果是,将 result 对象传递给该 callback 进行进一步的处理。
    6、通过xc_wx_jsapi_pay发起公众号支付请求,返回结果现在除了会监听【get_brand_wcpay_request:ok:支付成功】,还会对一下两种结果进行监听返回处理。1、get_brand_wcpay_request:cancel:取消支付,返回code=1。2、get_brand_wcpay_request:fail:支付失败(其它原因),返回code=1.
    7、在前端触发 xc_hook_payment_sdk 支付请求时,如果参数 environment 设置为 wechat,且支付方式 method 为 wxpay,则意味着服务端指定此次支付场景为 JSAPI(微信公众号支付)。此时,函数将调用 xc_wx_jsapi_pay(response, callback) 来处理支付请求,并对返回结果进行异步监听。系统会根据 callback 返回的 code 值触发相应的错误提示信息,以确保用户能够及时了解支付状态并进行相应的处理。
    8、修复统一支付接口返回错误【Undefined array key "method" in】时,该错误是由于前端在发送payment数组信息时,缺少了【method】键值导致的。默认情况下,系统会将第一个支付方式标记为ON。然而,针对公众号支付的特殊环境,此标识有时会出错。因此,必须在前端添加一个拦截处理机制。在发送ajax请求之前,需要检查payment对象的【method】字段是否为空。如果发现该字段为空,则应立即返回提示信息【请先选择支付方式】。通过这样的前端拦截和验证,可以有效避免由于缺失【method】键值而导致的后端错误,提高支付接口的健壮性和用户体验。
    9、在通过xc_get_payment_method方法生成支付选项时,如果$key == 'wxpay'(支付类型为微信)并且is_wechat(微信浏览器)条件成立,那么将直接标记为ON。因为在微信公众号支付场景中,微信支付方式必定是唯一且不可替代的。因此,为了优化用户体验并避免用户手动选择支付方式的步骤,需要在此种情况下自动将支付方式设定为ON。此外,除了微信公众号支付场景外,is_miniprogram(小程序支付场景)也需要做类似处理。对于处在微信小程序中的支付场景,同样需要直接将支付方式设定为ON,从而简化用户操作流程。
    10、修复了一个非常致命的错误。在执行公众号支付请求时,不论进行了怎样的操作,系统都会返回“支付失败:微信环境需登录后才能支付”的错误提示。实际上,初始化时是通过xc_is_login函数来验证用户登录状态,以确保用户已经处于登录状态。为了找出问题的根源,对xc_payment_hook函数进行了详细的溯源排查,最终发现问题出在一个运算符错误上。在支付过程中,系统会对创建支付订单的人和支付人进行身份验证,如果两者不是同一人则会返回对应的错误信息。然而,代码错误地将判断写成了【user_id = !user_id=!pay['user_id']】,这导致user_id变量被错误地修改,从而使后续的身份判断出错并引发支付失败。经过修正运算符,该致命错误终于得以解决。
    11、为了应对公众号支付场景中各类复杂情况,需要采用异步处理机制来处理各种返回结果。目前xc_wx_jsapi_pay支付事件已转换为使用Promise来处理返回的数组数据。在前端,可以通过await关键字来创建并处理异步任务,同时运用catch方法来捕获和处理可能出现的异常情况。目前支持的错误监听有【取消支付、环境异常、支付失败】三种。
    12、修复公众号支付场景,出现【下下单账号与支付账号不一致,请核实后再支付】错误返回的情况,经过核查在使用xc_payment_sdk_hook进行支付数据申请时,为了测试接口每次获取的openid(支付用户)都设置为固定用户,这导致微信官方识别出现异常,返回不一致的结果。目前已进行修复,通过mget_user_meta来读取付款人信息。
    13、公众号支付场景采用V3新接口来完成支付,服务端的处理逻辑保持不变,依旧是通过统一支付下单,然后调用SDK生成response数据包对象,并返回到前端进行处理。前端将通过V3接口【wx.invoke('getBrandWCPayRequest')】来拉起微信支付界面。这样可以确保前后端返回一致,不会因为跨场景支付出现回调异常的问题。
  • 0
    小小乐lv.2实名用户
    2024年7月19日
    1、在进行微信绑定关联操作时,返回结果中出现了【code=NULL、msg=NULL】的错误。经过调查,此问题的根源在于绑定请求发送到后端的xc_reg_hook无法被正确识别和解析。进一步分析表明,该问题源自提交的reg数组,如果是绑定请求,则type标识应改为【bind】,实际值应为wechat_bind。然而,错误却发生在验证码发送成功后,type标识被误改为了bind。这一错误导致后端无法正确处理微信绑定请求。因此,需要对验证码发送后的处理逻辑进行检查和修复,以确保type标识在微信绑定请求中保持为wechat_bind。
    2、修复微信公众号绑定验证码的问题,在xc_reg_hook进行验证码验证时,即使验证码正确,系统仍旧返回【验证码错误】的信息。经过详细分析,发现问题出在xc_sms_code_check_hook中的短信验证环节,该环节的验证标识被错误地写成了【wechat_bind_reg】,这是由于在动态解析type参数时发生的错误。已经对其进行了修正。具体修正方法是通过手动设置验证标识为【wechat_reg】,从而确保验证码验证过程中的标识正确。
    3、xc_login_hook登录钩子会对other_accounts变量进行初始化处理,将其默认值设置为false。如果该变量的值被设为true,则表示本次登录请求需要执行清理其它设备下线的操作,这种情况适用于诸如重置密码、禁止多设备登录以及安全信息重置等场景。然而,在正常的登录操作中,不会对这个变量进行任何操作,这导致了返回过程中出现错误信息【Undefined variable $other_accounts in】。因此,必须确保对其进行初始的初始化处理,以避免该错误的发生。
    4、微信公众号注册绑定功能已完成业务封装,当用户通过微信浏览器【含:微信电脑浏览器、微信小程序、微信网页】进行登录时,会自动通过鉴权获取对方的openid、unionid等参数,并且通过sql查询是否存在对应关联,如果不存在则强制用户跳转到注册绑定页面。在该页面,用户需要进行验证码验证,如果手机号已有用户,则变更为绑定。如果没有则为注册用户。
    5、微信自动登录接口已经进行了彻底的重构,现不再通过 wechat_mp_auto.php 文件内部手动验证参数。重构后的接口使用标准的统一钩子【xc_login_hook】来执行登录操作,并以【weixin】作为登录的唯一标识符。如果登录尝试失败(例如被拒绝),系统将通过 wp_die 输出具体的错误信息并立即终止执行流程,从而确保错误得到及时处理。相反,如果验证成功,系统将直接通过 wp_redirect 进行页面重定向,确保用户能够无缝地进入目标页面。这一改进大幅提升了接口的模块化和标准化,确保了代码的可维护性和扩展性,同时也简化了登录流程,极大地提高了用户体验。
    6、优化微信自动登录请求,获取到code凭证后,会先通过xc_is_login来获取用户状态,如果已状态,则强制页面刷新首页。禁止重复触发鉴权模式。2、如果用户未登录,则通过xc_weixin_login_openid方法进行鉴权操作,获取用户的openid,如果获取失败则将页面标记【openid获取失败,接口异常!】。如果获取成功,则通过wpdb构建查询语句,检查用户openid是否与数据库中【weixin_uid】记录匹配。如果匹配则触发xc_login_hook登录请求,根据返回结果执行错误提示或刷新首页访问。
    7、当通过xc_weixin_login_openid方法成功获取到用户的openid和unionid两个参数后,会立即通过setcookie函数将这两个参数写入到用户的浏览器cookie中。这样做的目的是为了在后续的微信SDK调用中能够快捷方便地提取所需信息。例如,用户在使用微信公众号支付功能时,系统只需从cookie中读取保存的openid和unionid即可完成相关的身份验证及支付流程。此外,当用户进行微信图片选择等涉及微信环境的事件操作时,也能通过先前存储的cookie数据来快速获取必要的用户信息,前端还可以通过检测cookie的存在与否,来判断当前用户是否处于微信浏览器环境中,以此对页面行为做出相应的调整和优化。
    8、鉴于外部加载的性能和安全性问题,决定将所有涉及到CDN.babylyf.com的weui组件调用全部移除。之前已经将这些组件进行了本地加载,因此移除这些外部调用不会影响系统的正常运行。需要注意的是,该域名的服务器位于香港,夜间经常会出现高延迟,导致加载过程中的丢包情况。因此,移除这些外部调用是一个必要且及时的举措。
    9、update_fingerprint用户指纹更新函数优化,在极个别的环境下(微信端开发工具)等场景会无法成功写入browser设备信息,此时直接执行$_COOKIE['browser']的读取操作,会直接返回错误【 Undefined array key "browser" in】
    间接的造成函数抛出异常。为了避免此类情况。在执行browser前会进行三元运算处理。
    10、用户来访请求事件:xc_user_visits_hook现在会通过isset检测是否存在【opneid】如果存在则获取并写入user对象返回前端,如果前端需要获取在微信环境中获取当前用户的openid只需要执行user.openid调用即可,如果获取失败说明用户环境不是微信客户端,或未授权登录。
    11、微信的openid读取机制进行了全面优化。在此优化中,首先确保该结果仅在用户登录的情况下才会返回,因为openid的获取依赖于用户的登录状态,这样可以有效提升系统的安全性。为了进一步加强数据获取的可靠性,除通过cookie获取openid外,还增加了在cookie获取失败时,通过get_user_meta来读取用户元字段【weixin_uid】的机制。这样设计的目的是确保在绝大多数场景下,openid值始终能够被成功获取
    12、xc_hook_payment_sdk 开始集成【微信公众号支付】功能。当服务端返回的参数包含【environment:wechat(微信浏览器)】并且method为wxpay时,表示本次支付请求是通过微信js-SDK完成的公众号支付。这种情况下,系统会首先检查user.openid是否存在。如果openid不存在,则会立即返回错误,提示【公众号支付失败:openid获取不到】。这一处理过程确保了只有在用户的openid正确获取的情况下,才能顺利完成支付请求
    13、在公众号支付的过程中,当服务端成功返回支付数据包信息之后,需要进一步检查payment.response是否包含发起微信SDK所必需的一些关键参数,即【appId、nonceStr、package、paySign】。这些参数对于确保支付过程的安全性和完整性至关重要,均需通过服务端的统一SDK进行鉴权操作后提取而来,从而保证其合法性和有效性。这些参数都是发起JS-SDK支付所必需提供的,以便确保支付流程的顺利进行和检测各环节的安全性。
  • 0
    小小乐lv.2实名用户
    2024年7月18日
    1、xc_reg_mp_weixin: 微信公众号注册绑定请求事件。该方法的执行流程如下:首先,通过xc_wechat_reg_phone_number函数获取用户在页面中输入的手机号码;接着,通过xc_mp_reg_code_phone函数获取用户输入的验证码;然后,通过mp_reg_type函数确定用户所选择的注册方式;最后,通过mp_reg_nickname函数获取用户在注册过程中输入的昵称信息。
    2、执行公众号账户绑定注册时事件时,前端在提交AJAX请求到服务端执行业务逻辑前。会通过xc_is_phone来检测wechat_reg.phone是否为true,如果不为则返回【请输入正确的手机号,目前仅支持国内手机】。同样的的验证码也会简单的检测处理。如果不存在或非6位数字则返回【验证码错误,请重新填写】。然后执行ajax请求【公众号注册绑定】,剩下的业务转交给服务端处理。
    3、服务端执行公众号注册绑定请求时,会执行以下验证。1、检测$_POST['wechat_reg']是否存在,如果不存在则说明非法请求。直接返回错误【传递信息不完整】。2、检测$_COOKIE['openid']是否存在,如果不存在则说明用户停留时间过长(大于5分钟)会直接返回错误【微信令牌过期,请重新进行授权】。3、使用xc_phone_regular检测用户提交的手机号,如果返回false则返回【手机号格式错误,目前仅支持国内号码】4、构建wpdb语句,查询usermeta数据表,检查weixin_uid是否已经有记录,如果已有记录则返回【微信号已绑定其它账户,无法完成注册】。
    4、如果微信公众号的处理来源是【$mreg_type == 'reg'】,那么将执行以下业务逻辑判断。首先,使用wpdb构建SQL查询,以检测该手机号是否已被其他用户绑定,因为每个手机号只能绑定一个账户。接下来,通过调用xc_is_nickname函数来检测用户本次提交的昵称是否符合规定,如果不允许则直接返回相应的原因。在执行昵称检测函数之前,系统会通过empty函数检测昵称是否为空,如果检测到昵称为空,则会返回【注册昵称不得为空】的提示信息。
    5、如果是绑定微信的情况,程序将首先执行【根据手机号进行查找和验证,具体操作是通过wpdb构建查询,以检测该手机号是否已经绑定过任何账户】。如果检测结果显示该手机号并未绑定过任何账户,系统将立即返回一个错误信息【手机号未找到绑定账户,请重新提交】,提醒用户重新提交正确的手机号。考虑到这是一个绑定请求,程序必须确保能够通过所提供的手机号找到一个关联的账户。在此过程中,该函数内使用的所有SQL查询语句都将进行优化,具体是使用$wpdb->prepare方法来构建安全的SQL查询,以防止潜在的SQL注入风险问题。
    6、服务端在处理【APP端微信注册绑定】请求时,将不再使用mb_strlen、validate_username、xc_nickname_detection这三个方法来验证昵称。此前,这三个方法分别用于检查昵称的长度是否合理、是否存在非法字符、格式是否正确以及是否重复。现在,这一系列验证过程将统一改为使用新方法【xc_is_nickname】来进行处理。这意味着,在用户进行APP端微信注册绑定时,昵称的所有验证需求将由【xc_is_nickname】这一新的方法来实现,确保操作一致性和可靠性。
    7、前端在发起微信公众号注册绑定请求时,会将所有所需的页面变量封装到一个称为【reg】的数组中。然而,服务端最近进行了重大调整,注册绑定业务的处理现在需要通过一个名为【xc_reg_hook】的钩子来完成,而不再使用之前的自定义处理方式。这一变化意味着,所有的注册和绑定请求在发送到服务器端后,服务器将通过【xc_reg_hook】钩子来接收和处理这些请求,从而确保系统的业务逻辑和流程的一致性和可扩展性。
    8、在统一注册钩子事件中,用户公众号的注册标识为:wechat。注册时需要主动传递以下信息:【nickname、phone、code、openid、avatarurl、unionid】。如果其中任一参数缺失,系统将返回“注册参数不完整”的提示。整个注册验证流程如下展开:首先,通过函数xc_phone_regular验证提供的手机号是否合格。接下来,利用函数xc_is_nickname确保注册使用的昵称符合规定。最后,系统会构建wpdb查询,检测提供的unionid是否在数据库中存在重复情况。对于这个参数,系统要求其具备唯一性,以确保注册用户的唯一标识。
    9、服务端不再通过cookie来获取avatar、openid、unionid这三个微信标识信息,而是改为在进入公众号的注册页面时直接验证参数是否存在。如果这些参数存在,则会将它们直接写入到自定义属性中。接下来,在执行ajax请求时,会从页面中提取这些参数,并进行数组封装。这样一来,就不必再担心由于cookie过期导致信息失效的问题,
    10、xc_reg_hook钩子已支持【wechat:公众号注册】请求,执行流程如下。1、使用xc_sms_code_check_hook:来验证本次短信验证码是否正确,如果不正确则拦截处理。2、使用redis_security_check执行注册拦截检测机制,防止短时间内大量注册行为。3、使用系统方法来构建账户注册和生成,并通过WP_Error对象来监听注册错误。4、完成账户创建,将用户相关信息通过meta写到到账户中。5、回调短信验证码,完成短信业务的处理。6、调用xc_login_hook方法完成注册登录流程。
    11、在执行公众号注册绑定请求(wechat_bind)时,函数xc_reg_hook会进行以下一系列验证处理。首先,该函数会检查几个关键参数【phone、code、openid、avatarurl、unionid】是否存在,如果任意一个参数缺失,则会直接返回错误提示,指出绑定微信参数不完整。如果这些参数齐全,则进入下一步验证流程。函数将首先验证提交的手机号是否合法有效,确保其格式和内容都是正确的。接着,它会检查提交的openid是否存在绑定记录,注意这里不能通过unionid来验证,必须严格按照openid进行验证。最后,它会验证该手机号是否已绑定在一个现有的账户中,如果查询不到绑定记录,则会返回【绑定失败: 该手机未关联平台账户】,提示用户提供的手机号未与任何平台账户关联,从而终止绑定过程。
    12、xc_reg_hook钩子已支持【wechat_bind:公众号绑定】请求,执行流程如下。1、验证关联账户【手机号】是否存在,如果不存在则返回错误【绑定失败: 该手机未关联平台账户】。2、通过xc_sms_code_check_hook方法验证短信码是否有效,如果无效则返回错误。3、将wechat_unionid、wechat_avatar、weixin_uid写入到绑定用户资料中,完成微信账户的注册关联。4、调用xc_login_hook方法进行登录,登录的标识【weixin】。
    13、修正执行绑定微信请求时出现的错误。后端返回了一系列错误信息,包括【Undefined array key "reg" in】、【Trying to access array offset on value of type null in】以及【Undefined array key "type" in】。这种错误归因于前端在初始化reg对象时的语法错误。正确的初始化方式应当是使用{}来创建对象,而不是使用[]来创建数组。
  • 0
    小小乐lv.2实名用户
    2024年7月17日
    1、微信公众号注册页面重构优化:针对用户头像样式存在椭圆现象的问题,进行了使用 CSS 代码的修正处理,使其展现出更加美观和统一的效果。为此,我们设置了如下调整细节:通过 height: 25vw; 来设定头像的高度,同时与宽度保持一致,从而确保头像呈现出标准的正圆形状。此外,为了完美遮盖住任何超出圆形容器的部分,我们采用了 overflow: hidden 属性,使得多余部分不会显示并影响整体美观。最后,object-fit: cover 属性的使用,保证了头像图片在填满容器时能够自适应调整,并且保持其长宽比例不变,使得图片既不会变形,也能够完美地展示在规定的区域内。
    2、mp_reg.php页面优化:在微信注册页中引入CSS和JS文件的方式进行了改进。原先通过手动设置域名地址引入资源,这样当域名变更时,旧地址会失效,导致无法访问对应的样式表。现在将这种方式优化为使用home_url函数来动态获取当前网站的域名地址。这样一来,无论域名如何变化,页面都能够正常加载相应的样式表和脚本文件
    3、在微信的注册页面中,为了提升用户协议和隐私协议的展示体验,不再通过iframe内嵌的方式打开,而是采用新的协议标准短代码来实现。具体地,使用以下短代码:do_shortcode('[xc_protocol type="user"]') 和 do_shortcode('[xc_protocol type="privacy"]') 来输出并创建这些协议内容。这种实现方式不仅提高了页面的加载效率和用户阅读体验,而且在协议内容需要更新时,只需调整短代码的响应内容,就能自动适配所有相关页面,实现了一处修改,处处生效的效果
    4、微信注册页面,验证码获取方式进行重构处理。接入统一验证码组件。绑定事件:xc_hook_sms_code来执行验证码获取,移除旧版的验证码获取方式。该场景的验证码绑定的ID属性为【xc_mp_reg_code_phone】。注:重构微信注册页面逻辑,就是为了让验证码组件能集成进来。所有的短信验证码都必须通过统一来发送。
    5、新增短信场景配置【微信公众号注册验证码、短信唯一标识:wechat_reg、短信模版ID:1667287、该短信模版文本:您的注册验证码:{1},如非本人操作,请忽略本短信!、每日发送次数上限:5次、短信验证码有效期:300秒、发送间隔时长:60秒、用户绑定手机号:关闭状态、登录用户才可用:关闭状态】。当用户通过公众号进行微信绑定或注册时,将会使用这个短信场景进行验证。
    6、前端手机短信发送钩子【xc_hook_sms_code】已集成wechat_reg场景的短信发送请求,如果是该场景会检测用户页面是否包含xc_mp_reg_code_phoneu元素,如果未包含表明用户并未处于公众号注册页面,此时会直接返回错误提示【页面参数异常】,并阻止用户进行短信发送请求。如果存在则对获取到的手机号,进行xc_is_phone验证,如果返回false则提示【请输入正确的手机号<br>注:目前仅支持国内手机号码段】。如果上述问题不存在则触发ajax请求到服务端处理。
    7、在微信注册页面进行优化短信发送事件处理时,遇到了一个问题:由于该页面没有正确初始化weui组件,所以在调用$.hideLoading方法时,会触发“is not a function”错误。这导致创建或隐藏加载指示器的操作无法正常执行。然而,短信发送事件确实需要使用这个方法。为了避免错误中断整个流程,如果当前操作在微信注册页面发生,我们将主动在函数中过滤掉对hideLoading方法的调用。这确保了即使在未初始化weui组件的情况下,短信发送事件也能顺利进行而不会引发错误。
    8、xc_get_avatar方法进行全面升级,现在新增了一个返回字段【avatar_url】,用于获取用户头像的URL地址。此字段通过正则表达式直接从$list['avatar']中提取图片的src属性,并将其赋值给avatar_url,从而减少了额外的SQL请求。这种改进显著提升了性能,尤其是在许多场景下,只需要用户头像的URL地址,而无须整个头像HTML代码的情况下,这一变化变得尤为重要。通过此升级,系统可以更高效地处理用户头像信息,满足各种不同的应用需求。
    9、服务端的 xc_sms_code_hook 针对【wechat_reg:微信公众号注册绑定手机】短信发送请求时,会执行特定的业务处理。首先,通过构建 wpdb 进行 SQL 查询,检查当前手机号是否已经绑定过账户。如果手机号已经绑定了账户,则获取对应的用户UID,并使用 xc_is_login_weixin 方法检测该用户是否已绑定过微信账号。如果检测到该手机号已经绑定了微信账号,则返回错误信息【短信发送失败:该手机号已绑定过微信】。这种处理流程不仅确保了系统的安全性和准确性,还防止了用户重复绑定同一个微信账号,从而提高了用户体验和数据的一致性。
    10、在进行微信公众号注册或绑定验证码发送的过程中,如果用户输入的手机号码已经绑定了一个现有账户,那么注册操作将自动转变为绑定操作。在这种情况下,系统会通过调用xc_get_avatar接口来读取该用户的头像数据,并将读取到的头像数据返回并存储在$result['avatar']中,以便前端业务逻辑能够根据用户头像进行对应的适配处理。此外,最初发出的注册验证码也会相应地转换为绑定验证码
    11、在APP微信注册和公众号微信注册这两个事件中,检测用户绑定微信状态存在一个潜在的问题。不能简单地依赖xc_is_login_weixin方法来验证用户是否绑定了微信,因为这个方法有其局限性。微信应用场景复杂多样,比如微信公众号生成的openid和APP微信SDK生成的openid并不相同。这些不同的openid通过微信唯一标识weixin_unionid进行关联。也就是说,即便用户在APP中绑定了微信,并不意味着用户在微信公众号中同样完成了微信绑定。因此,采用weixin_unionid来验证用户微信绑定状态是较为可靠的方式。此外,正确的处理方法应是读取相应的元字段进行检测,而不是直接使用单一的方法进行验证。具体而言,公众号微信的用户ID字段为weixin_uid,APP微信的用户ID字段为weixin_app_uid,而PC端微信的用户ID字段则为weixin_apc_uid。通过分开读取这些元字段,可以更准确地判断用户在不同平台上的微信绑定状态,从而避免误判和数据混淆。
    12、微信公众号注册的短信发送成功后,前端会进行一系列判断和操作。首先,它会判断变量msg.avatar是否存在,如果存在,这意味着当前操作是绑定微信,而非首次注册。此时,页面的交互动作如下:1、将用户界面上的微信头像更新为绑定的头像。2、在页面上显示一段提示文字,内容为“该手机号已绑定XXXX,短信验证后微信将直接关联账户!”。3、移除原有的昵称输入表单,并将页面中的提交按钮从“注册微信账户”更改为“绑定关联微信”。如果用户是首次注册微信账户,则系统会还原上述所有操作,恢复到初始状态。
    13、当完成微信公众号的注册验证码发送后,该系统会根据两种不同场景——绑定和注册,来自动调整【mp_reg_type】属性值。初始情况下,该属性值默认为【REG】,如果场景为绑定,则会将其变更为【bind】。在页面提交验证码验证时,需要调用函数:xc_reg_mp_weixin。该方法会将页面中的【手机号、验证码、注册绑定方式、用户昵称】一并传输到服务端进行相应的处理。
  • 0
    小小乐lv.2实名用户
    2024年7月16日
    1、前端发起退款订单查询时,服务端会使用xc_is_payment_order_visit方法进行验证。如果返回code=1 则表明用户不具备退款查询权限,此时会对其进行拒绝返回处理,拒绝原因来源于返回msg。避免退款订单信息出现非法查询的情况。同时前端发挥退款信息时,会阻止data的访问,仅返回文字提示。退款成功货退款失败的信息。
    2、在账单详情页中,如果当前支付订单产生了平台收益,则会在页面底部显示具体的收益金额。这些收益通常来源于各种交易活动,例如鉴定报告、淘货交易、商户拍卖等,凡是涉及第三方交易结算的订单,都会在结算时产生相应的收益金额。这些金额都被记录在支付订单表的【$payment['income']】字段中。需要注意的是,该字段仅对超级管理员可见,其他用户无法查看。
    3、在账单详情页中,新增了一个第四个容器(box),专门用于管理可见的内容。该容器仅对前台管理员或超级管理员开放,确保只有具备相应权限的用户才能查看其中的信息。这个容器将用于展示一些较为敏感的数据,确保信息的安全性和隐私性。为了实现这一功能,我们通过调用 xc_is_admin 函数来判断当前用户是否具备访问权限。只有当 xc_is_admin 函数返回用户是前台管理员或超级管理员时,才会显示这个专门的容器,
    4、在账单详情页中,对退款记录容器进行扩展,新增一个表单字段用于展示【退款方式】。该字段将使用Switch语句进行解析,并且固定返回三种类型,以便用户清晰地了解退款的渠道。具体来说,退款方式分为以下三种:1. admin:由平台管理员发起的退款;2. seller:由卖家主动发起的退款;3. system:由系统自动执行的退款行为。通过这种方式,用户可以更方便地知晓每笔退款的具体发起渠道。
    5、账单详情页,管理员可见的内容包括:1、付款IP:显示订单支付时用户的IP地址信息,用于追踪支付来源。2、设备指纹:展示用户在支付订单时手机设备的唯一标识信息,确保交易安全和防范欺诈行为。3、退款失败原因:在订单退款失败时,通过$meta['refund']['fail']记录具体的错误信息。例如,【(BNORMAL:退款异常)疑是银行卡被冻结,需要平台手动退款】,帮助管理员快速定位问题并采取相应措施。4、退款失败时间:详细记录退款失败的具体时间,格式为Y-m-d H:i:s,方便管理员进行后续处理和分析。
    6、新增公共查询页面【global/query_payment.php】页面唯一标识:xc_query_payment,该页面允许用户通过支付订单号、商户单号查找账单详情。有两种场景会使用到。1、普通用户:微信支付宝有个订单很奇怪,知道是宫论付款的,但是记录太多不好找。那么直接复制订单号,一键直达账单详情页。2、财务、管理、客服收到用户支付订单疑问反馈,需要查看账单详情,需要用户提供单号。进行账单详情查看,以便进一步处理。
    7、后台页面管理 - 强制登录页面配置,将账单查询页也添加到强制登录的页面列表中。如果用户尝试在未登录的状态下直接访问该页面,将会被系统强制拦截,并提示用户先进行登录操作。同时,账单查询页的页面设计已经完成。在页面的正中间,放置了一个显眼的输入框,其placeholder文本为【请输入支付或商户单号】,引导用户输入订单相关信息。在输入框的右侧,紧邻一个搜索按钮。用户只需提供订单号,然后点击搜索按钮,即可发起账单查询功能,从而查看相关账单信息。
    8、在账单查询页面,不仅展示了用于输入查询信息的表单,还通过使用 xc_empty_page 函数输出了一条页面提示,告知用户【支付单号可以在支付宝或微信的账单中查看】。使用户能够更方便地找到所需的支付单号,从而顺利进行账单查询操作。这一提示信息位于查询表单的显眼位置,确保用户在输入查询条件之前能够清晰地了解到相关信息,减少查询过程中可能遇到的困惑和难题。
    9、支付订单JS脚本新增了一个函数:xc_payment_query()。这个函数被绑定在查询按钮菜单上,当用户点击查询按钮时,函数会首先触发前端的账单查询请求。在正式发起服务端请求之前,该函数会进行两次基础拦截检查。首先,通过调用xc.is_login()方法检测用户是否已经登录。如果检测到用户未登录,则会强制用户跳转到登录页面,以确保只有登录用户才能进行后续的操作。其次,函数会使用jQuery提取用户输入的支付单号,并进行验证:如果用户输入的支付单号不是纯数字,或者输入的数字长度少于10位,函数将反馈一个错误信息,提示用户填写的单号不准确,要求重新输入。
    10、xc_payment_query查询函数优化处理:为了提高系统的安全性和防止非法提交,对查询函数进行了优化处理。在此过程中,增加了页面元素检测机制。在执行请求之前,函数会通过jQuery库检查页面上是否存在元素xc_payment_lnquire_code。如果该元素不存在,则可以判定用户当前并不处于账单详情页,这意味着可能存在非法请求。因此,在这种情况下,系统将直接返回一个标志非法请求的响应,不会进行后续操作。如果检测通过,即元素存在,则系统会继续进行下一个步骤。此时,函数将触发一个Ajax请求,提交页面上的订单号参数至服务器,进行订单查询操作。
    11、服务器端已经完成了【xc_payment_query:前端账单订单查询】请求的处理。首先,系统会通过 $_POST['order'] 获取查询单号,如果单号为空或者不是数字,系统将返回错误信息。接着,系统通过 xc_is_login 方法获取登录用户的UID,如果获取失败,这表示用户尚未登录,系统会返回错误信息并提示用户登录后再操作,同时附带参数 jumlp=login,前端会自动跳转到登录页面。如果用户已经登录,系统将执行Redis上锁检查,锁的标识是 payment_query:+IP。该接口限制每五秒只允许调用一次,如果调用频率超过限制,系统会返回错误提示。完成上述检查后,系统将调用 xc_is_payment_order_visit 方法来验证用户是否被允许查看订单信息。如果被允许查看,系统将返回 code=0 表示成功;如果不被允许查看,系统将返回具体的错误原因。
    12、优化服务端返回的账单结果,当前用户拥有查看支付单号的权限时,系统将额外返回一个变量【link】,并通过短代码完成封装处理。这个【link】将会指向具体的账单详情页。前端在接收到查询结果时,会先判断【link】是否存在。如果【link】存在且响应代码为0,那么系统将调用【xc_mobile_url(link);】方法进行页面跳转,打开相应的账单详情页。如果账单详情链接获取失败,系统则会直接使用【xc_msg】方法返回错误提示信息。这一优化确保了具备权限的用户能够直接访问详细账单,同时在链接获取失败时能够及时收到反馈。
    13、对xc_payment_query前端查询账单的方法进行优化:在执行ajax请求之前,将首先调用xc_loading_show方法弹出加载提示器,显示“查询中”的状态。在接收到服务端响应结果后,将使用xc_loading_hide方法隐藏加载指示器。与此同时,当账单查询成功后,将进行页面跳转机制的细节调整——会显示提示信息【账单查询成功】。为增强用户体验,页面跳转将通过setTimeout函数进行延迟设置,延迟时间为1.5秒后再执行跳转到账单页面。
  • 0
    小小乐lv.2实名用户
    2024年7月15日
    1、账单详情页重构数据的读取方式,不在通过wpdb来构建sql查询来获取订单详情页,不在使用switch来解析支付订单表获取【commend、commend_1、background、title】四个字段参数值,不在使用xc_sql_order来读取订单信息数据。这些方法太过笨重,并且已经进行过时。几乎每新增一个支付场景就要手动修改信息。维护非常不便。
    2、支付账单页详情页移除【<style></style>】的自定义样式写入,这个会导致IOS16+版本出现返回上级页面卡死的现象,页面所需要的层叠样式表直接使用[data-page="pay_order_details"]方法写入到page.css中。同时支付订单详情页新增一个专属类【pay_order_details_content】用于锁定表单的样式控制与美化,并且页面通过通用类名【grey】来讲背景色变成浅灰色。
    3、支付订单详情页的数据现在是通过xc_order_access返回来捕获,返回的值会赋值到【order_access】变量,然后payment会提取变量的data部分【$order_access['data']】。这里面包含了支付订单数据表的完全数组信息,后需页面所需要的参数都是通过payment数组来提取。页面本身不会进行二次SQL的查询。比如需要meta的json对象,那么只需要通过$payment['meta']完成提取即可。注:只要页面能打开,那么必定能够通过拦截事件返回订单数据。
    4、账单详情页第一个页面容器是【商品短代码】,如果$payment['shop_order']存在,则表明支付订单存在商品信息。那么将使用do_shortcode('[xc_shop_card type="'.$payment['shop_type'].'" order="'.$payment['shop_order'].'"]')来输出商品卡片信息。之前是通过switch解析参数来手动拼接,现在直接一键解析,不需要去手动维护。只需要进行样式单独美化和调整,适配订单详情页即可。
    5、账单详情页通过调用 xc_is_pay_config 函数来解析并获取当前支付场景的配置信息。获取到的信息将被赋值给变量 pay_config,后续如果需要使用支付配置参数,只需直接从这个数组中提取即可。目前,支付订单信息将从 pay_config 数组中提取支付场景名称【$pay_config['name']】,并展示在付款详情页面中。例如:如果支付场景是账户余额充值,则显示为【支付场景:recharge_money(账户余额充值)】。
    6、在账单详情页中,第二个页面容器被设计为【付款详情】,用于展示详细的付款信息。该页面包含一个菜单表格,具体内容如下:商品标题为“账户余额充值”;支付方式包括“微信付款”、“支付宝付款”和“余额付款”;支付场景同样为“账户余额充值”。此外,表格中还显示付款单号,即支付平台生成的付款单据号;商户单号,则是宫论内部的商户编号。实付金额为0.12元,付款时间以“Y-M-D H:i:s”的格式显示。
    7、账单详情页内容列表展示优化:首先,支付场景将不再转换为中文类型,而是直接输出其对应的key(令牌标识)。其次,支付方式将通过switch遍历循环输出,如果是wxpay则显示“微信支付”,如果是alipay则显示“支付宝”,如果是money则显示“余额支付”,若不属于上述任何一种情况则显示“其它支付”。同时,支付金额将以红色高亮显示,并在前面增加一个人民币符号“¥”。此外,表单的CSS样式也将进行调整,容器宽度最大设置为60Vw,内容不允许换行,若内容超出容器宽度则以省略号代替。
    8、在支付订单列表容器的右上角新增一个复制按钮,用户点击该按钮后,将会自动复制以下信息:【购买商品:账户余额充值\n付款单号:2024062822001444731406785835\n商户单号:171952674161622226\n付款方式:支付宝\n实付金额:¥ 0.10\n付款时间:2024-06-28 06:19:07】。复制成功后,系统将弹出提示,显示【支付订单信息复制成功】,以便用户确认信息已经成功复制到剪贴板。
    9、在支付订单详情页中,我们需要增加一个表单字段来展示【收款人】的信息。如果订单涉及支付交易对象(例如淘货商品、商户拍卖商品、鉴定报告等),那么最终的收款人将是【卖家、商户或鉴定师】。在数据库中,我们有一个字段名为seller(卖家),用于存储收款人的信息。如果该字段存在,我们将在支付订单页面上展示该信息,并输出卖家的昵称,以便用户清楚地了解交易的收款信息。这一改动旨在提高用户体验,使用户在支付时能够准确地知道收款方是谁,从而增加交易的透明度和信任度。
    10、在支付订单信息中增加一个状态栏,通过使用switch语句来检测payment['state']的值,从而标记订单的不同状态。如果payment['state']的值,从而标记订单的不同状态。如果payment['state']等于"wait_pay",则标记为“等待付款”;如果等于"ok",则标记为“付款成功”;如果等于"close",则标记为“订单关闭”;如果等于"wait_refund",则标记为“正在退款”;如果等于"refund",则标记为“退款成功”;如果等于"fail_refund",则标记为“退款失败(需人工处理)”;若不属于上述状态,则标记为“其它”。为了更清晰地展示订单状态,状态输出将使用按钮边框包裹,使其在界面上更为醒目和易于识别。
    11、账单详情页目前通过使用empty函数来检测$payment['refund_order']是否存在,如果该字段存在,则表示该订单涉及退款行为。在这种情况下,页面会创建一个名为find-box的容器,用于展示详细的退款信息。这个容器内将按顺序显示退款单号、退款金额、退款时间以及退款方式,确保用户可以清晰地了解每一笔退款的具体情况。
    12、在退款详情信息中,额外展示退款说明信息。此外,如果当前用户是订单的付款用户,还会在页面底部显示一个按钮,按钮上标注“对此订单存在疑虑”。用户点击该按钮后,将被引导至支付订单咨询页面,通过客服了解订单的更多详细信息。需要注意的是,目前客服系统尚未上线该功能,因此用户点击按钮后,会收到提示信息:“投诉功能即将上线!”
    13、在账单详情页的退款容器上新增了一个【实时查询】按钮,点击该按钮会触发绑定的事件:xc_refund_query(order)。这个前端函数会向后端发起业务请求,查询与支付单号相关的退款状态。后端负责处理这个请求的接口是【xc_refund_query_hook】,该接口通过SDK进行查询,确保返回的结果是有效且可靠的。当前端接收到后端返回的查询结果后,会通过xc_msg在页面上显示提示信息,告知用户订单的具体状态情况。
    14、优化前端查询退款状态的处理,增加了多重安全机制。服务端在执行请求之前,会通过xc_is_login方法检查用户的登录状态。如果用户未登录,系统将拒绝该请求并返回错误信息“请先登录后再操作!”,同时附带额外的字段jump: login,前端接收到该字段后会自动跳转到登录页面。此外,为防止暴力非法请求,该接口使用Redis实现简单的锁拦截机制,限制用户每隔5秒才能查询一次退款状态。拦截机制是基于用户IP地址来处理的,如果请求频率过快,系统将返回错误信息“查询速度过快,请稍后重试”。
  • 0
    小小乐lv.2实名用户
    2024年7月14日
    1、修复发起订单退款,并且成功。无法触发【payment_refund】统一消息接口的问题,正常情况下一旦发生退款,金额会进行原路返回。此时系统会触发【短信、邮件、公众号、站内信、服务号、APP】等渠道消息,告知用户订单完成退款。经过接口排查,导致通知无法触发的原因为xc_notify_hook接口,如果将最后一个变量设置true,则表明启用异步下发。但是退款接口目前还未实装异步进程。这导致请求被无效化。
    2、修复进行退款通知时,接口意外返回【Warning: Undefined array key "amount" in】错误的原因,退款成功会通过宫论服务号下发消息。其中有个菜单是【支付金额】这里的字段获取方式是$push_data['payment']['amount'],但这是错误的读取,正确的方式应该是pay_amount。因为数据库的金额指是这个。
    3、退款服务号通知消息结构优化:现在会显示标题【退款商品】XXXXXXXX。方便用户更容易理解推送通知,同时remark底部信息也会显示退款原因:xxxxxxxxxx。方便用户退款的原因。同时订单号优化展示,防止因为过长超出页面表单。展示方式为通过substr进行字符阶段,只展示订单号末尾10个数字。
    4、退款通知信息已进行了全面优化,不论是哪种消息通知形式,只要涉及到金额的调用,都会在金额后面加上一个元字。例如,支付金额会显示为:0.1元,退款金额也会显示为:0.1元。此项优化适用于短信、邮件、模版消息和APP通知。此外,服务号消息现在也已支持用户点击【查看详情】按钮,直接打开关联的支付订单详情页,方便用户查阅详细信息。
    5、后台支付配置页新增了一个字段:xc_pay_admin_config,该字段用于设置支付订单的白名单列表。除了管理员外,名单内的用户也可以查看其他人的支付订单信息。为了方便管理,设定为数组结构,需要填写两个字段。第一个字段是name,对应的是姓名或备注,用于标识对方的身份,这样可以更便于管理名单。第二个字段是user_id,即用户的账户UID,这个字段确定了该用户可以查看支付订单的付款信息。
    6、新增一个is检测函数,xc_is_pyament_oreder_visit。该函数需要主动传递ID变量(支付订单表的主键ID参数),函数会通过xc_is_login来获取当前用户UID,并通过WPDB来构建sql 然后查询对应的支付订单记录,如果用户不是支付用户,则会返回错误。函数返回标准的数组结构:code=0代表有权访问,code=1是无权访问。msg是错误原因。
    7、考虑到xc_is_payment_order_visit函数可能会用于订单详情页的访问,而该页面的访问机制可能涉及多种方式【ID主键、支付单号、商户单号】,因此函数在处理GET变量时需要具备更高的灵活性。如果只支持ID主键,却不支持支付单号或商户单号,会导致函数返回无权限错误。为了避免这种情况,函数在构建WPDB查询语句时会先检测传递的ID长度是否大于10。如果长度大于10,系统会通过ID主键进行查询;否则,系统将使用pay_order和payment_order字段进行查询。通过这种优化,函数可以同时支持三种不同的支付订单查询方式。
    8、xc_is_payment_order_visit函数已完成封装,执行流程如下:接收订单号 $id 作为参数,初始化了结果数组 result 和权限标志 admin,通过调用 xc_is_login 检查用户是否登录,未登录则返回未登录的提示信息,然后检查订单号是否为数字,若不是则返回订单号必须为数字的提示信息。接着,使用全局变量 $wpdb 获取数据库连接,根据订单号的长度构建不同的查询语句,并获取管理员配置选项 xc_pay_admin_config 提取管理员用户ID数组 user_ids,执行查询语句获取订单信息 $payment。随后,检查查询结果是否为空,若为空则返回订单不存在的提示信息,接下来检查用户是否为订单所有者或管理员,若是则将权限标志 admin 设为 true,最后,如果用户有权限则返回成功提示信息,否则返回无权查看该订单信息的提示。
    9、支付订单列表页【/global/pay_order.php】和支付订单详情页【/global/pay_details.php】已加入强制登录页面配置数组中,访问这两个页面的时候,如果用户未登录则会拦截访问。拦截处理方式为:页面初始化时会通过require_once加载ajax_page.php脚本,脚本会根据请求页面地址执行相应的拦截处理,如果未登录则强制跳转403页面。
    10、支付订单详情页已集成并支持【xc_order_access】访问拦截事件,拦截的标识为【payment】,需要主动传递$_GET['order']。访问拦截钩子如果来源未【payment】会调用xc_is_payment_order_visit方法来检测用户是否具备访问权限,如果返回code=0则表明用户具备权限,此时会将allow变量标记为TRUE,防止进行页面拦截。
    11、xc_order_access页面拦截钩子重新设计,之前的设计是该函数仅负责页面拦截,根据页面标识和传递的参数进行效验,如果效验不通过返回allow=false。执行通用403页面跳转。重构的后钩子基础页面不变,但是增加一个数组返回机制。具体为:一开始就会返回初始result为空数组。如果执行拦截过程中需要进行参数传递,那么通过result进行处理即可。这个数组会最终返回。
    12、优化处理xc_is_payment_order_visit钩子,提升支付订单数据访问的效率。如果用户有权查看支付订单数据,函数会将相关订单数据封装到[data]变量中,以便后续业务直接提取和使用。对于支付订单详情页,当通过xc_order_access方法进行访问拦截处理时,它会直接将xc_is_payment_order_visit返回的订单数组写入$redult['payment']键值中。这样避免了订单详情页二次SQL查询,从而减少性能损耗,提高系统响应速度和用户体验。
    13、后台支付场景配置组新增两个字段【1、title:当前支付场景的简称,固定两个字(示例:余额、充值、淘货、定金、转账)。必须为两个字,不能多也不能少。很多页面会涉及到调用。2、color:配套颜色选择,默认值为#46c47c。可以根据实际情况来调整支付配置颜色,会在支付订单列表/支付订单详情页进行菜单调用】,当前已配置的支付场景均以重新适配上述两个字段。
  • 0
    小小乐lv.2实名用户
    2024年7月12日
    1、宫论系统计划配置中心【间隔10分钟】计划任务,新增计划:支付宝【退款中】订单查询处理函数,关联函数「xc_corn_alipay_wait_refund」。通过SDK发起订单退款请求时,如果订单是支付宝付款类型,执行退款会产生一个状态(fund_change缺失)账户资金未发生变化。支付宝也暂时无法确定是否退款成功。出于业务保护设计,此时会将退款标记为成功返回。但是退款订单标记为等待退款中。需要定时计划调用接口接口延迟查询是否完成退款,进一步变更订单状态】。
    2、间隔定时计划脚本【recurring_task.php】已集成支付宝退款查询处理函数,该函数触发后会执行以下流程。1、构建WPDB,查询xc_pay数据表,字段pay_select等于【alipay】并状态等于【wait_refund】的所有记录。如果没有则跳出任务执行,如果有则将去转为数组,并使用foreach进行遍历循环操作。以此执行xc_refund_query_hook方法来进行退款查询。如果返回code=1,则将支付订单表状态标记为fail_refund。如果返回code=0则将支付订单表状态标记为refund。
    3、支付宝退款查询确认计划,细节优化处理。时间调度进行调整,通过wpdb构建语句进行优化处理,在 SQL 查询中,添加 AND refund_time < NOW() - INTERVAL 10 MINUTE 条件,确保只检索退款时间超过10分钟的记录。注:如果不加时间保护,刚退款的订单,正好触发了定时计划的执行。仍然会处于【fund_change】缺失的状态,导致被标记退款失败。10分钟的缓冲就可以避免,支付宝基本百分百已解决上述的问题。
    4、xc_corn_alipay_wait_refund继续优化处理,如果同时有多个支付宝退款记录处于(wait_refund)则会在每次for循环中对payment_refund进行初始化处理,避免出现继承问题。同时如果确定退款失败了,会解析原记录中的 meta 字段 将其转为数组。然后写入$meta['refund']['fail'] 本次退款失败的原因返回, $meta['refund']['time']当前退款的时间。然后更新sql的时候也会更新meta。客服财务后面的页面能看到退款失败的原因。
    5、定时计划xc_corn_alipay_wait_refund如果确定将付款状态从wait_refund变更成fail_refund,则会在业务逻辑之后 触发【xc_payment_refund_abnormal_hook】方法。用于预留钩子通知财务或客服人员介入退款事件。至此,支付宝待定退款计划任务已完成封装。查询获取【wait_refund,根据处理情况将订单主要变更为refund或fail_refund】。
    6、宫论系统计划配置中心【间隔30分钟】计划任务,新增计划:微信【退款中】订单查询处理函数,关联函数「xc_corn_wxpay_wait_refund」。通过SDK发起订单退款请求时,如果订单是微信付款类型,执行退款会产生一个状态(PROCESSING)正在退款中,请售后查询。一般是退款到银行卡,需要等银行卡方面确认回调。微信也暂时无法确定是否退款成功。出于业务保护设计,此时会将退款标记为成功返回。但是退款订单标记为等待退款中。需要定时计划调用接口接口延迟查询是否完成退款,进一步变更订单状态】。
    7、xc_corn_wxpay_wait_refund函数执行逻辑基本与支付宝退款确认逻辑保持一致,不过执行周期从10分钟变成30分钟,同时触发的xc_payment_refund_abnormal_hook方法标识改为【wxpay】,避免对应的通知接口出现故障。同时微信退款回调接口做出调整,回调的订单状态支持【refund:退款成功、wait_refund:等待退款中、fail_refund:退款失败】三种状态。确保官方回调是始终有效可靠的。
    8、微信退款定时计划存在一个保护机制,会使用meta记录【wait_refund_corn】字段值,每次执行退款订单查询,如果都返回code=1,那么会在字段基础上进行计数+1处理。如果失败次数达到了3次,才会将订单标记为fail_refund。注:如果连续三次都返回异常,基本可以判断退款存在异常,需要人工进行确认处理。
    9、人工退款通知机制已全部集成,无论退款来源是哪种【alipay支付宝、wxpay微信】,只要判断退款出现异常(fail_refund:订单确认已标记退款了,相关业务已处理。只是退款过程中出现故障)。就会触发xc_payment_refund_abnormal_hook钩子事件。该钩子负责通知财务或管理员进行进一步跟进处理。注:包括不限于以下场景会出现标记「1、退款SDK明确表示退款出现异问题,一般为银行卡收款有问题。2、系统定时计划请求退款过程,出现多次错误,那么也会将其标记异常。3、退款回调通知,收到支付平台的消息。明确百世该订单无法完成退款」。
    10、退款流程逻辑流程整理:1、通过钩子【xc_payment_refund_hook】发起退款请求。钩子会做各种基础时间事件拦截,确保退款请求是安全可靠的。2、退款请求方式支持三种,卖家退款、系统退款、管理员财务退款。不同的退款渠道处理的逻辑各不相同。3、余额退款最简单,直接通过余额更新完成操作即可。微信和支付宝退款则通过SDK来完成。4、退款SDK做全量try-catch异常监听,确保退款的请求是安全可靠的。如果出现异常会记录日志,并触发报警。5、SDK如果成功取得数据,会进行解析,根据状态执行不同的处理【退款成功、退款中、退款异常、退款失败】。6、退款成功和退款中都视为退款中,并触发回调事件执行后续的业务逻辑。7、退款过程中会建立redis安全锁,保证线程的安全可靠性。8、退款失败会记录异常,并将结果和次数写入到META字段。9、退款成功回调钩子,支持计数器写入工作。将退款总金额、退款方式金额、退款场景金额分别记录到计数器中。10、退款成功会触发对应的通知事件,以短信、站内信/APP、邮件、公众号来下发通知给收款用户。11、退款如果明确出现异常【订单退款发起,但是原路退回出现故障,服务商无法完成打款】会触发对应的钩子,要求财务或管理进行审查并进行手动退款。11、微信退款支持订单回调处理,通过签名验签来获取退款信息,然后对退款订单进行状态标记处理。12、集成开发退款查询接口,提供【支付订单号、支付单号、商户单号】之一,发起退款查询请求,查询订单是否退款成功。13、增加两个定时计划,微信退款确认、支付宝退款确认。对订单状态【wait_refund】进行处理,调用退款查询接口,来确定订单是否完成退款,然后执行对应的订单回调。14、退款过程中,订单数据表直接通过wpdb来读取,禁止使用任何缓存,确保数据是可靠有效的。更新数据表则必须通过xc_update_sql方法来处理,确保缓存同步更新。15、退款确认失败,会写入meta字段【退款失败原因:['refund']['fail']、退款失败时间:['refund']['time']】,后续审核人工打款页面,会显示该内容。16、退款过程中,支付订单处于【退款成功、退款等待人工处理、退款中、等待退款】都会在支付订单表中创建生成:退款单号、退款时间、退款金额、退款原因等信息。17、退款过程中,通过宫论统一支付SDK来完成操作。只有发生异常(无法打款)才会需要人工介入。18、退款流程非常复杂,涉及到平台资金的安全。后续还有很多调整需要完善。核心诉求一点,确保退款线程的可靠性,保证商户资金的安全性,确保支付退款记录可溯源跟踪。
  • 0
    小小乐lv.2实名用户
    2024年7月11日
    1、执行退款查询前,会验证查询获取到的订单表 refund_order字段是否为空,如果为空则直接返回【查询结果:该订单未发起过退款请求】。与之对应的使用wpdb构建数据表查询匹配支付订单,增加第四个匹配方式,允许ID变量为:refund_order,查询数据库的时候会匹配refund_order查找值,如果匹配成功页会返回对应关联记录。
    2、如果支付订单是wxpay(微信支付)订单。则会无视state状态。然后读取订单退款单号,然后执行方法【\Yansongda\Pay\Pay::wechat()->query($order)】发起退款请求,并将返回结果赋值到refund_result。所需要的order是数组,有两个参数值。1、transaction_id:退款单号,通过支付订单表获取。发起退款必定有这个参数。2、_action请求方式:refund。返回的几个会赋值到refund_result。然后使用toArray将其转为数组。
    3、考虑到调用SDK发起查询请求会出现各种错误异常,特地采用try-catch方法来监听各种错误,避免出现异常导致返回非法字符(前端无法解析和接受参数)。目前已支持的监听错误有1、GatewayException:处理支付网关异常。2、InvalidArgumentException:无效参数异常。3、InvalidSignException:签名或验签异常。4、Exception其它异常。注:无论是那种异常,都会返回code=1msg=异常的说明。
    4、微信退款查询接收到SDK返回结果后,会使用empty和isset来检测refund_result参数,如果不存在或者缺失键值则返回错误【返回异常:SDK返回不可识别的错误】。然后对$refund_result['status'] 进行参数值判断,如果等于CLOSED。则返回【查询结果:CLOSED-退款关闭】、如果等于ABNORMAL:则返回【查询结果:ABNORMAL-退款异常】、如果等于PROCESSING则返回【查询结果:PROCESSING-退款处理中】。如果等于SUCCESS,则表明退款成功,直接返回code=0.查询结果:退款成功'。
    5、为了满足后续接口对退款信息的更详细需求,通过 xc_refund_query_hook 发起的微信退款请求,如果成功捕获到【SUCCESS:退款成功】状态,不仅会返回 code=0,还会将SDK返回的所有信息封装成数组结构,并写入 data 键中一并返回。这样,后续进行相关业务逻辑处理时,可以直接通过 data 提取相应的键值。
    6、统一退款业务集成【支付宝订单】退款查询,处理流程如下:如果本次查询的订单来源为【$payment['pay_select'] == 'alipay'】会使用require_once方法加载统一支付SDK,通过require_once语句引入微信的统一支付SDK,以便进行后续的操作。接下来,通过调用xc_payment_config_hook函数来获取支付宝支付SDK所需的配置信息,并将该函数返回的配置信息赋值给变量config。最后,通过执行\Yansongda\Pay\Pay::config($config);方法,完成支付宝SDK的初始化操作。
    7、如果支付订单是【alipay:支付宝付款】订单,那么会构建order数组,里面包含三个键值;1、out_request_no:退款请求号。 请求退款接口时,传入的退款请求号。2、out_trade_no:商户订单号。 订单支付时传入的商户订单号,和支付宝交易号不能同时为空。3、trade_no:支付宝交易号。】这三个参数都通过订单表提取。完成数组封装后,将调用Yansongda\Pay\Pay::alipay()->query($order)方法进行退款查询,并将返回结果传递到refund_result。
    8、如果退款查询来源是支付宝订单,为防止SDK返回异常导致结果出错,将采用 try-catch 方法捕获各种错误,目前支持的错误包括 GatewayException(处理支付网关异常)、InvalidArgumentException(处理无效参数异常)、InvalidSignException(处理签名或验签异常)以及 Exception(处理其他异常),无论遇到哪种异常,都会返回 code=1 和包含异常说明的 msg。
    9、通过SDK获取到支付宝退款信息后,会通过toArray将对象转为数组结构。然后使用empty和isset检查数组是否有效,如果不存在或参数缺失则直接返回错误【返回异常:SDK返回不可识别的数据】。然后对返回字段【refund_status】进行检查,如果返回REFUND_SUCCESS则代表退款成功,直接返回code=0。如果不存在或为其它值则表明正在退款中,或退款失败。需要进一步处理。
    10、支付宝退款查询如果成功获取到SDK的结果后,会将SDK返回的所有信息封装成数组结构,并写入 data 键中一并返回。这样,后续进行相关业务逻辑处理时,可以直接通过 data 提取相应的键值。同时如果$refund_result['refund_status']不存在时,不在返回通用字符【SDK返回异常信息】,而是尝试检查$refund_result['sub_msg']是否存在,如果存在则直接返回这个字段。注:这个字段是官方错误返回,可以更清晰了解返回错误的原因。
    11、通过SDK查询支付宝订单是否完成退款时,存在这样的一种现象。【如果退款查询发起时间早于退款时间,或者间隔退款发起时间太短,可能出现退款查询时还没处理成功,后面又处理成功的情况】这种情况返回的结果是退款失败的,但是其实处于不确定的状况。为了避免这种现象,在最终返回文字上会做出区别对待。读取支付订单表的退款时间,并进行运算对比。如果退款时间迄今已超过30秒,则直接返回【查询结果:退款失败】,如果小于30秒则返回【查询结果:退款失败(可能正在退款,请稍后查询)】。注:30秒,可以确定退款请求已处理完毕,返回的结果是可靠的。
    12、为了确保退款查询的准确性,通过 xc_refund_query_hook 发起【微信、支付宝】退款查询时,无论订单状态如何,每次都会通过支付SDK调取最新的退款记录,确保返回结果的有效性和可靠性。退款查询涉及交易安全,尤其是在确认发货时,系统会调用SDK查询对方支付订单是否存在退款记录以及是否完成付款。如果任一条件不匹配,系统将拦截支付操作。
    13、宫论统一退款查询接口xc_refund_query_hook()已完成封装,以下场景会调用该接口来确保交易安全。1、进行订单发货,结算货款等交易场景,为了确保资金安全需要通过退款订单查询来确定资金是否还在。如果不在则需要主动拦截。2、退款接口存在延迟问题。需要定时计划来遍历确认退款是否到账,这时就需要主动调用退款查询,来进一步确定订单是否完成退款。3、订单出现异常退款,需要财务进行手动打款。此时需要进一步确认查询订单是否完成过退款。避免二次打款。
    14、为了确保线程的安全可靠,如果用户登录状态。退款查询接口会做次数限制,防止用户暴力查询,造成安全隐私泄露。1、如果用户已处于黑名单,则直接拒绝接口使用。2、正常用户每分钟可以最多查询5次,超过5次,则会限制5分钟才能继续查询。3、管理员或客服限制每分钟最多查询10次。4、超级管理员则不做任何限制。注:通过redis做用户计数器做拦截处理,达到次数自动触发非法拦截请求。
  • 0
    小小乐lv.2实名用户
    2024年7月10日
    1、支付订单表新增两个字段状态【1、wait_refund:正在退款中,当退款订单处于不确定是否完成退款时写入。比如已提交了退款请求,但是用户银行卡结算有延迟,就会处于该状态。2、fail_refund:明确表示订单退款出现失败,可能是账户异常、用户被冻结、总之打款失败的情况就会写入该字段】。在执行xc_payment_refund_hook方法进行退款操作时,如果为wait_refund,返回退款失败:该订单正在退款中<br>如果三天内未到账联系平台客服。如果为fail_refund:退款失败:需要联系官方客服进一步处理
    2、alipay_payment_success_log日志写入函数进行优化处理,新增第二个变量【refund】默认为false。如果将其设置为true则表明本次的日志写入是记录退款回调记录。则执行日志写入的时候不再是以【/log/payment/alipay/2024-07-08.log】方式来写入。而是以【/log/payment/alipay_refund/2024-07-08.log】方式来写入。记录对应的退款回调记录,方便进行订单追溯。
    3、当catch捕获到异常时,会进行一个判断。读取当前支付订单的META字段,并使用json_decode想起转为数组。然后检测$meta['refund']['number']是否存在,如果存在则在原有基础上+1处理。如果不存在则将其变为1。然后将退款失败的原因写入到$meta['refund']['reason']字段,将 $meta['refund']['time']写入当前时间日期。然后通过xc_update_sql方法来执行sql更新,将新的meta字段【有退款失败次数、退款失败原因】写入到支付订单数据表。
    4、支付配置页面新增字段:xc_pay_retund_number_fail:系统退款拦截,当通过系统方式进行退款。若连续失败X次 则自动视为成功【执行成功退款逻辑】。并将订单标记为fail_refund(需要人工客服介入处理)。防止系统层面的退款出现死循环,一直退款失败,一直被系统任务执行。后面堆积的订单越来越多,造成不可挽回的奔溃。
    5、如果对【微信或支付宝】付款订单进行退款操作时,如果出现catch异常错误。则会从meta字段中读取失败次数,如果退款来源系统,并且累计退款次数达到后台限制,则视为订单退款成功。此时会更新原支付订单以下参数【meta、state、refund_order、refund_amount、refund_time、return_content】。其中state字段为:fail_refund。然后返回code=0,msg=订单退款成功。注:系统退款失败X次,返回成功。执行退款正常业务流程,同时将订单标记为退款失败,等待人工手动退款。
    6、微信退款回调接口优化:如果微信发挥退款信息【['refund_status'] == 'ABNORMAL'】则会检索对应的支付订单获取meta字段,并将其通过json_decode转为数组。然后执行计数写入。并将reason退款失败原因写入【ABNORMAL:退款异常,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败】。确保退款失败,都能通过meta获取到对应的原因。
    7、退款发起后,无论是否退款是否退款成功,都会写入$meta['refund']['way']字段【固定值为:seller卖家退款请求、admin:超级管理员退款请求、system:系统退款请求】。在查询退款订单的时候,如果需要知道退款渠道或者来源,则完全可以通过meta提取way来获知。
    8、meta字段进一步优化处理:为了确保业务的安全性。现在回通过meta字段来记录退款用户UID,方便订单退款溯源操作。具体操作为:首先通过empty来判断user_id是否存在(直接已通过xc_is_login获取)如果存在则在$meta['refund']['user_id']中写入用户USER_ID。同时为了保证进一步溯源,会使用$meta['refund']['ip']字段来进入对方IP地址信息。查询支付退款订单时,可以根据iuser_id知道退款发起方是谁,并使用IP进一步查询到溯源信息。
    9、进行微信退款时,如果SDK接口直接返回【ABNORMAL:退款异常,疑是银行卡被冻结】那么也会判定退款成功,执行支付成功的业务逻辑,并返回code=0。但是支付订单状态标记为【fail_refund:需要管理员或财务前往商户平台,进行手动退款操作】同时返回【订单退款请求已提交\n,需要平台手动进行退款(72小时完成处理)】。
    10、通过xc_payment_refund_hook发起订单退款时,会在基础拦截过后设置一个订单锁,防止业务执行过程中出现同一订单退款请求。这个锁之前没有进行释放机制。这导致卖家或管理员在退款时,返回异常。继续点击退款查看确认会出现【退款失败:重复请求(订单锁)】,这是不符合设计需求的。正常来讲,只要返回前端结果 就可以主动取消锁,以便后续请求能执行。为此:退款函数在执行return方法,都会触发xc_unlock($redis_key)函数来移除订单锁。
    11、新增后端钩子:xc_refund_query_hook,支付订单退款查询钩子。该钩子需要传递支付订单数据表ID,函数内会调用支付订单数据表记录,如果查找到则获取商户单号或支付单号,使用SDK接口发起退款查询状态,然后根据返回结构来返回信息。钩子返回标准的数组结构,code=0代表退款成功,code=1代表退款失败。msg是退款失败原因。需要注意的是,退款失败的原因有很多,需要根据msg来分析原因。
    12、退款查询钩子优化:id变量现在支持三种参数查询【1、支付订单(id)用于主键参数查询。2、pay_order:支付订单号(微信和支付宝是平台生成,余额付款是自己生成的)。允许通过付款单号来完成支付操作。3、payment_order:商户单号,系统自动随机生成。】这三个查询方式都是唯一查询。传递参数时,会进行验证。如果ID通过is_numeric方法返回false,则提示【查询失败:订单号必须为数字】。使用strlen获取ID参数的长度,如果短于10则以ID主键查询(ID主键递增不可能超过十位数)。否则查询数值是否等于pay_order或payment_order。
    13、统一退款查询钩子xc_refund_query_hook,已支持余额退款查询。处理逻辑如下:首先检测支付订单表是否匹配成功,如果未成功匹配则直接返回【查询结果:订单不存在】。如果查询成功,如果订单状态处于refund,则代表订单确定已完成退款,可以直接返回code=0,查询结果:该订单已完成退款。如果状态不是refund,并且支付方式是money。则直接返回code=1,退款未完成。注:余额支付订单业务逻辑很简单,只需要判断支付订单表的状态即可。
    14、微信退款查询处理的逻辑是,首先需要查询支付订单表中的字段【pay_select】,以确定订单的支付来源是否为微信支付。如果该字段的值为wxpay,则表明该订单是通过微信付款完成的。在确认支付来源为微信支付后,通过require_once语句引入微信的统一支付SDK,以便进行后续的操作。接下来,通过调用xc_payment_config_hook函数来获取微信支付SDK所需的配置信息,并将该函数返回的配置信息赋值给变量config。最后,通过执行\Yansongda\Pay\Pay::config($config);方法,完成微信支付SDK的初始化操作。
  • 0
    小小乐lv.2实名用户
    2024年7月9日
    1、修复微信退款请求发起后,如果SDK返回PROCESSING(退款进行中),不会执行sql数据表更新的问题。这直接导致微信退款回调钩子,无法触发对应的事件。正常的执行流程如下:先将支付订单表状态变更为【wait_refund】,然后通过系统异步回调来更新数据表最新状态。导致无法执行的问题是xc_update_sql函数在更新支付订单表时,没有提前初始化table_name变量导致,这个变量决定更新指定数据表。
    2、wxpay_payment_success_log日志写入函数进行优化处理,新增第二个变量【refund】默认为false。如果将其设置为true则表明本次的日志写入是记录退款回调记录。则执行日志写入的时候不再是以【/log/payment/wxpay/2024-07-08.log】方式来写入。而是以【/log/payment/wxpay_refund/2024-07-08.log】方式来写入。记录对应的退款回调记录,方便进行订单追溯。
    3、通过wxpay_callback.php接口处理退款回调通知时,如果refund_status返回状态为【SUCCESS】则代表本次退款已到账,此时会调用wxpay_payment_success_log方法来写入日志,日志内容为微信接口返回的完整数据包。该日志会和支付日志一样,以Y-M-D格式切割存储。后期如果觉得退款存在异常,可以通过此处日志来检查溯源。
    4、支付日志清理定时计划,现在支持退款日志的清理。当通过【corn_clean_old_logs】函数去清理XX日的日志文件的时候,除了会清理【支付宝:alipay/Y-M-D.log、微信支付:wxpay/Y-M-D.log】的记录外,还会清理与之对应的退款日志文件【wxpay_refubd、alipay_refund】。这里的清理机制和支付回调一样,沿用后台字段:xc_payment_callback_log_days。
    5、新增钩子:xc_payment_refund_abnormal_hook【支付订单退款异常监听钩子】1、退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败。2、退款时用户收款账户已被注销或冻结,不可接收退款时也会触发。该钩子需要传递两个变量【1、type:固定值(wxpay、alipay)判断是微信支付还是支付宝。2、refund_order:退款的订单号,通过这个订单号来读取支付订单表】。注:第三方支付,如果涉及到退款。如果因为异常导致退款失败,需要做进一步监听处理。比如主动联系对方完成退款操作。对于这种特殊情况,提供一个预留钩子比较合理。后期需要监听可以直接通过这个钩子来完成业务处理。
    6、修复SDK发起微信退款时存在的两个问题,1、如果处理结果是【正在退款中】其返回的json无法正常解析,问题源于:字符中存在BR换行,这导致json无法解析。解决方案换行符改为\n。2、微信退款回调接口,会将退款金额重置为0.00。具体表现为,收到退款请求后,回调接口为了安全会提取退款金额,然后更新到数据表中。更新过程中退款金额金额获取失败,导致变成0.
    7、微信退款接口已完成封装,执行的流程如下。1、通过xc_payment_refund_hook接口发起退款请求,并执行对应的拦截事件处理。完成验证后调用SDK发起退款请求。并根据结果进行订单回调操作。2、正在退款中货退款成功直接返回退款成功,并触发通知成功接口。3、回调接口集成退款请求操作,如果退款订单状态处于【refund、wait_refund】会根据验签取得的数据包进行二次订单回调,将退款金额、状态、日期更新到订单数据表中。4、在执行回调过程中,会写入对应的日志。无论是退款成功还是退款失败都会触发对应的日志。
    8、宫论统一订单退款接口增加【alipay:支付宝订单】的退款请求,通过xc_payment_refund_hook钩子发起退款,如果订单支付来源【$payment['pay_select'] == 'alipay'】则会执行统一支付SDK初始化行为,通过require_once加载宫论SDK,并使用xc_payment_config_hook方法来获取SDK所需要的配置参数,然后调用\Yansongda\Pay\Pay::config方法完成SDK的初始化行为。
    9、成功初始化退款SDK后,会建立一个order订单数组对象,里面包含本次支付宝退款的所有参数信息。【refund_amount:本次退款金额,该数值不得大于订单金额。out_trade_no:商户订单号。 订单支付时传入的商户订单号,商家自定义且保证商家系统中唯一。refund_reason:退款原因说明。 商家自定义,将在会在商户和用户的pc退款账单详情中展示。out_request_no:退款请求号。 标识一次退款请求,需要保证在交易号下唯一,如需部分退款,则此参数必传。】
    10、使用SDK发起支付宝订单退款时,可能会遇到各种错误返回。为了防止返回结果干扰整个钩子事件,会采用try-catch来处理各种错误异常。目前已支持的监听错误有1、GatewayException:处理支付网关异常。2、InvalidArgumentException:无效参数异常。3、InvalidSignException:签名或验签异常。4、Exception其它异常。注:无论是那种异常,都会写入日志到refund,并返回code=1.
    11、 当微信或支付宝发生退款异常(refund_status=ABNORMAL)时,会通过xc_payment_refund_abnormal_hook函数执行sql更新动作,匹配xc_pay支付订单表退款字段【refund_order】相一致,并且状态为【refund或wait_refund】的记录。将其的状态变更为【fail_refund】注:凡是fail_refund的记录,属于关联的上哦订单已变更为退款状态,但是用户未收到相关款项。需要管理员或平台客服跟进处理。
    12、通过SDK发起支付宝退款请求后,会对返回结构进行解析处理。首先使用toArray方法,将返回的对象强制转为数组结构。然后判断$refund_result['code']是否等于10000,如果不等于则代表本次请求失败,直接返回错误码1,并尝试读取sub_msg字段,然后将其写入到日志【refund】,方便运维人员进一步排查。如果等于10000则代表退款请求发起,此时会进入验证。检查是否存在fund_change字段,如果存在并且值等于Y,那么代表退款成功。此时会执行对应的sql将支付订单数据表更新为refund,如果不等于则代表退款发起了,但是还没到账。此时将支付订单状态变更为wait_refund。注:如果是退款发起但是未到账,也会返回code=0,但是文字信息为:订单退款请求已提交\n,如果超过三天未到账,请联系平台客服进行处理。。
    13、通过 SDK 发起支付宝退款请求时,可以在构建退款订单数据时额外提交一个参数 query_options,并设置其值为 deposit_back_info。该参数的作用是标记本次退款需要获取银行卡冲退信息。注:在某些情况下,退款可能会退到用户的银行卡中。这种情况下,退款的到账时间可能会有所延迟。为了确保退款能够准确执行并及时获知退款状态,支付宝收单系统会根据银行回执消息发送退款完成信息。具体来说,当退款请求中添加 query_options 参数并设置为 deposit_back_info 后,支付宝会在处理退款时,额外查询并返回银行卡冲退的相关信息。
    14、通过微信或支付宝发起 SDK 退款请求时,无论退款成功与否,都需要对返回的内容进行处理。具体来说,首先要判断返回的内容是否为数组。如果返回内容是数组,则将该结果存储到 $result['data'] 键位中。这样,上级函数就可以直接通过 $result['data'] 来进行进一步的分析和处理。
  • 0
    小小乐lv.2实名用户
    2024年7月8日
    1、账户余额退款流程完成,当需要退款的时候将通过执行【xc_payment_refund_hook】来发起退款请求,完成基础安全验证,如果原支付订单是money(余额支付)则将执行xc_update_money_hook方法来增加对方退款余额,如果退款成功【code=0】那么将执行xc_update_sql来更新支付订单表记录状态和对应自动字段。最后使用xc_payment_refund_ok_hook方法来下发退款通知,以短信、站内信、邮件、APP、公众号模式告知用户订单完成退款。
    2、统一支付订单退款事件,开始对接微信支付退款请求。使用xc_payment_refund_hook方法发起退款请求,如果订单支付类型是【wxpay】则会在基础拦截事件后,会使用require_once加载统一支付SDK,然后使用xc_payment_config_hook方法获取支付配置信息,并赋值到config。最后调用\Yansongda\Pay\Pay::config($config)方法来完成支付配置加载,完成微信支付SDK接口的初始化行为。
    3、微信退款SDK一旦初始化,会构建一个order订单数组 其中包含以下键值【1、out_trade_no:支付订单中的商户单号,通过xc_pay数据表中提取payment_order字段来写入。2、out_refund_no:商户退款单号,商户系统内部的退款单号,商户系统内部唯一,使用xc_order函数来随机生成。3、amount:退款金额子数组,refund:退款金额(分为单位),total:订单金额(分为单位),currency:货币单位固定值(CNY)】。完成数组的封装,则执行Pay::wechat()->refund方法来发起退款请求。
    4、微信退款数组订单封装完毕,在原有基础上增加【reason:退款原因】键值,在下发给用户的退款消息中体现退款原因。该键位读取$refund['remake']。out_trade_no:读取$refund['payment']['payment_order']。refund读取$refund['amount'] * 100。total读取$refund['payment']['pay_amount'] * 100。注:订单金额和本次退款金额需要在原有基础上进行乘以100,将支付订单转为分。微信官方仅支持分单位的金额传递。
    5、统一订单退款钩子:xc_payment_refund_hook在完成基础拦截后,会在原有的refund数组结构下新增一个键值【refund_order】退款订单号,使用xc_order()来生成。不管是余额退款还是微信、支付宝退款,都需要提供一个商户自动生成的退款单号,为了统一处理(后续回调接口能捕获到这个单号),特定做全局封装。在执行退款前进入业务处理前,就提前封装进去。避免每个退款场景单独去生成。
    6、通过统一退款钩子进行微信退款时,会使用try-catch来捕获各种异常。防止返回结果出现不可识别导致的错误情况。目前支持的捕获异常有1、GatewayException【支付网关异常现象】。2、InvalidArgumentException:【无效参数异常】。3、InvalidSignException【签名异常】。4、Exception【其它异常返回结果】。上述错误都会返回code=1,并携带getMessage原因。
    7、后台日志报警配置新增【退款日志】。日志唯一标识:refund,当微信或支付宝退款接口出现异常时,会触发日志写入并根据配置下发报警通知。 如果当天累计出现3次错误。则会触发报警通知管理员。同时为了避免出现异常出现大量重复警告,每日报警上限设置为3次。该报警短信通知开启。触发报警会同时下发短信、邮件、公众号、APP通知。
    8、通过SDK发起微信支付退款请求时,会对返回体进行判断。如果refund_result不是数组 或者$refund_result['status']不存在则会返回错误【退款失败:接口返回内容错误】。然后对status字段进行参数值检查,如果等于CLOSED则返回错误【退款失败:返回状态(CLOSED:退款已关闭)】,如果等于PROCESSING则返回【退款失败:返回状态(PROCESSING:退款处理中)】。如果等于ABNORMAL则返回【退款失败:返回状态(ABNORMAL:退款异常)<br>疑是银行卡被冻结,需要平台手动退款】。
    9、退款日志优化:统一的日志写入格式为【[退款时间 - ' . date("Y-m-d H:i:s") . '] [退款渠道 - ' . $payment['pay_select'] . '] [错误 - ' . $e->getMessage() . '] [退款单号 - ' . $payment['id'] . ']】。并且除了catch监听到的错误,还会对$refund_result['status']字段进行监听,如果不是成功则会返回对应错误并进行日志写入。写入的错误码与微信返回状态信息保持一致。
    10、如果微信退款成功status=SUCCESS,则会通过执行xc_update_sql方法来更新对应的支付订表。将state、refund_order、refund_amount、refund_time、return_content字段变更为指定参数值。完成更新后,会继续执行后函数【xc_payment_refund_ok_hook】,下发退款成功回调钩子。通过短信、邮件、公众号、站内信等渠道来告知付款用户订单已完成退款。最后返回code=0、msg=订单退款成功。
    11、宫论支付订单新增一个状态【wait_refund】代表订单退款正在处理中,实际的退款场景存在这样的一个现象。通过微信或支付宝进行订单退款,如果是银行卡付款,那么退款到账有个延迟,大概时长为:几分钟到几天。支付接口此时会返回【PROCESSING】状态,退款发起了,但是还在处理中。不能代表退款成功。
    12、通过微信API接口进行退款时,如果状态返回PROCESSING也会视为退款成功。并且额外执行以下事件。1、通过xc_update_sql写入本次退款请求,但是status状态标记为:wait_refund(等待退款中)。2、继续执行退款成功回调钩子:xc_payment_refund_ok_hook。3、返回code=0,msg【订单退款请求已提交<br>如果超过三天未到账,请联系平台客服进行处理】。注:PROCESSING代表退款正在进行,因为退款到账需要时间,很多时候发起退款请求都会返回上述状态码,这个不能代表退款成功,也不能代表退款失败。但是前端一律视其为成功返回。
    13、宫论微信支付统一回调接口现在已支持退款回调通知,当收到微信发送的订单数据包,会使用SDK进行解析签名验证,如果验证成功。则会检查$result['resource']['original_type']是否存在,如果存在则判断值是否等于【refund】。如果是的话则代表这是退款回调。那么将进入单独事件处理。首先捕获返回字段refund_status是否等于CLOSED或ABNORMAL,如果等于则代表本次退款失败。将支付订单表变更为【fail_refund】。如果等于SUCCESS则代表退款成功,将订单状态变更为【refund】。
    14、回调接口在确定回调为退款来源,会通过wpdb构建一个sql。查询和检索支付表【refund_order】等于$result['resource']['ciphertext']['out_refund_no']记录,并且state状态等于【refund、wait_refund】的记录。如果命中则获取主键ID,然后使用xc_update_sql方法进行支付订单回调。将【state变更为refund或者wait_refund】,将refund_amount退款金额变更为$refund['resource']['ciphertext']['amount']['refund']。将退款的时间变更为当前日期。完成上述的处理,返回【[ 'code' => 'SUCCESS', 'message' => 'OK', ]】结束整个退款回调流程。
  • 0
    小小乐lv.2实名用户
    2024年7月6日
    1、xc_payment_refund_ok_hook退款成功钩子新增事件:退款金额计数器,通过xc_redis_count函数已【refund】作为统计标识,以$refund['amount']作为计数值进递增。记录每日平台累计订单退款金额数量。可以通过get_redis_count($key)获取计数器统计详情,支持查询【总数、今日、昨日、本周、上周、本月、上月、今年、去年】多维度的计数器查询统计。注:这个计数器可以监听每日平台退款的金额总数。
    2、为了更好的统计订单流向,后续财务报表更详细。退款订单的计数器现在支持类型统计:refund是退款订单总数,在此基础上延伸【退款方式】计数统计。1、【计数器】支付宝退款成功金额累计(refund_alipay)。2、【计数器】微信退款成功金额累计(refund_wxpay)。3、【计数器】余额退款成功金额累计(refund_money)。这样做资金对账更方便。完成退款后,会自动添加总退款和对应支付方式退款。
    3、宫论统一订单退款钩子xc_payment_refund_hook,在完成基础的安全拦截后,会在退款数组中额外写入两个变量。1、$refund['type']:支付订单的类型,比如tao:淘货商品、money:账户余额充值等。用于标记付款场景。2、pay_select:付款方式 固定值为money(余额付款)、wxpay(微信付款)、alipay(支付宝付款)。这两个参数都是为了减少后续sql读取【退款回调钩子和对应的挂载事件都会用得到】,在钩子内直接通过继承payment数组来获取。
    4、退款事件预留付款场景计数器,示例:refund_【$refund['payment']['type']】,根据支付订单场景来写入。比如余额充值订单退款,那么就会写入计数器【refund_recharge_money】。如果是淘货订单退款,那么就会写入计数器【refund_tao】。如果后续要监听退款场景记录,可以通过上述计数器来读取对应的数据。但是这里需要特别注意的一点,因为计数器是需要写入后台才会做到每日自动重置,因为支付场景非常广泛,不可能一一去写入。只能后期根据需要再后台添加。这里默认只统计总数,如果需要按日统计,则需要手动处理。
    5、全局PUSH通知管理:新增消息通知场景【payment_refund:【资金变动通知】订单发生退款通知】,当用户支付的订单发生退款时,会触发这个通知场景。该通知分类为:资金变动通知。触发函数【xc_payment_refund_ok_hook】该通知场景目前仅考虑服务号站内信消息通知,短信、公众号、APP、邮件渠道都关闭处理。绝大部分退款场景,都会专门建立场景通知渠道,将根据场景的不同,执行不同的通知行为。这里统一的退款通知,只需要建立一个服务号【退款】消息记录即可。
    6、新增宫论服务号:【退款通知:refund】,关联用户UID:34。服务号介绍:当用户支付的订单发生退款时,将会通过这个服务号下发一条消息通知。该服务号开启了站内弹窗,如果用户在线情况,会收到对应的服务号消息提醒。私信功能:未启用 用户无法对其进行发送私信消息。注:该服务号消息与余额助理基本类似,只要发生退款就会创建一条消息记录,方便用户查询回看退款记录。可以将服务号当成退款记录列表查看页面。
    7、xc_payment_refund_ok_hook触发时,会构建push_data数组并写入以下键值【ip:当前客户端访问IP、ua:当前客户端设备信息、fingerprint:指纹信息参数、amount:本次退款金额、pay_select:本次退款的方式、pay_order:本次退款的支付订单号、type:本次退款的订单来源(支付场景)、title:本次退款的金额。】然后执行调用xc_notify_hook通知接口,开始进行消息通知。通知的标识为【payment_refund】。
    8、退款成功的服务号消息完成封装,站内消息结构如下。标题:💰 订单退款通知。正文:你支付的订单发生了退款,退款金额:' . $push_data['amount']。第一栏:退款单号:' . $push_data['payment']['pay_order']。第二栏:订单金额:' . $push_data['payment']['amount']。第三栏:退款金额:' . $push_data['amount']。第四栏:退款时间:' . date("Y-m-d H:i")。备注区域:$push_data['remake']。注:退款通知是根据场景来决定的,通用事件只会触发服务号消息。
    9、退款push消息通知现在支持【站内信+服务号】内容点击跳转事件,跳转的link为【支付订单详情页,通过短代码进行指向】[xc_link type=global]/pay_details.php?order='. $push_data['payment']['payment_order']。通过传递商户单号,完成支付订单页的跳转处理。支付订单详情页可以查看一些付款信息,包括付款时间、付款商品、付款金额、付款渠道。如果发生退款,还会显示退款时间、退款金额、退款编号、退款说明。
    10、退款通知服务号消息,模版展示内容结构进行优化,在原有的内容基础上增加【first头部】字段,用于展示退款商品的简称【$push_data['payment']['title']】,示例1:账户余额充值。示例2:【淘货】民国景德镇出产的红彩山水纹碟。同时服务号模版消息菜单文字进行调整:退款订单改为订单(订单号读取原付款单号,非常长,简化处理),订单金额改为付款金额。
    11、新增通用短信模版【支付订单退款通知】,模版ID:2207734,模版内容结构:尊敬的用户,您购买的商品 ({1}) 已完成退款,退款金额为 {2} 。支付金额已原路退回,请注意查收。如有任何疑问,请联系客户服务。感谢您的理解与支持。「1」商品标题,通过支付订单title字段来提取。[2]本次退款金额,加上退款原因。示例:33.2元,退款原因:系统超时自动退款。注:退款场景非常多,如果每个场景都去写通知事件,工作量以及后期维护非常大 综合考虑。还是做统一的退款通知,所有的退款场景都沿用一个退款消息。
    12、后台退款成功通知配置已开启邮件提醒,每日最多提醒五次。邮件标题:宫论提醒您:退款已经成功。邮件正文:您好, 您的付款订单 ' . $push_data['payment']['payment_order'] . ' 已经达成退款。 商品:' . $push_data['payment']['title'] . ' 退款金额:0.00 【退款原因:xxxxxxx】。支付金额已原路退回,请注意查收。如有任何疑问,请联系客户服务。感谢您的理解与支持。
    13、后台退款成功通知配置已开启公众号模版消息通知,每日最多提醒10次。模版ID:NyqU2_oGQYHG6NW71NFjom29OQsCHKmwHaIJdX-Lyg4。模版标题【退款通知】。第一栏:退款原因(展示订单支付的商品标题,$push_data['payment']['title'])、第二栏【退款金额:$push_data['amount']】。注:公众号模版已进行改版,移除了first头部信息和remark底部信息。因此通知不能完整呈现,只能做简单展示。
    14、后台退款成功通知配置已开启APP消息通知,APP标题:💰 订单退款通知。正文:你支付的订单发生了退款,退款金额:' . $push_data['amount']。绑定link事件,点击后会触发页面跳转行为。注:退款统一通知事件已支持【站内信、退款服务号通知、公众号模版短信、手机短信、APP消息通知、电子邮件】全场景通知,只要退款成功就会通过payment_refund来触发上述通知,告知用户支付订单完成退款流程,
  • 0
    小小乐lv.2实名用户
    2024年07月5日
    1、新增统一支付退款钩子:xc_payment_refund_hook 该钩子需要传递ID【支付订单主键ID值】,宫论所有的订单,如果涉及到退款都必须通过这个钩子来进行。钩子内部会设置各种安全拦截,确保退款场景是安全可靠的。钩子返回标准的数组结构,code=0代表订单完成退款,code=1代表退款失败,msg是失败的详细原因。注:退款涉及到平台资金安全,处理需要特别谨慎。原则上,订单发送退款只能有两个用户发起。卖家、超级管理员。如果涉及到系统退款逻辑,需要鉴权处理。
    2、宫论统一退款钩子额外增加两个变量。1、amount:退款金额,需要同时支持全额退款和指定金额退款功能。产生退款的时候,需要主动传递金额单位。2、data:退款涉及到各种场景,需要的参数信息各不相同。因此增加一个数组变量来处理。特定场景的需要的参数通过数组来传递即可。系统退款如果涉及到降权操作,也可以通过数组来传递加密字符,以便完成鉴权操作。该数组是可选的,默认情况下是空数组。
    3、后台支付配置页面,新增字段【退款秘钥参数】,系统相关退款事件,会检查这个参数来做安全保护。场景示例1:用户在宫论APP下单购买了一个淘货藏品,但是卖家失联了。超过XX天仍旧会发货,此时系统会自动发起退款操作。场景示例2:用户发起退货请求,卖家超时未进行受理。此时系统也会发起退款行为。这个退款过程中为了确保安全,会检查退款秘钥参数,如果未传递或者传递错误秘钥则视为非法请求,退款行为会被强制终止。
    4、订单退款方式目前规划有三种。1、seller:由订单卖家主动发起的退款行为,通常为【关闭订单,取消订单,同意退款,主动退款】等。订单为B2C(商户订单、鉴定订单、淘货订单)类型才能发起。2、system:由系统来完成的退款行为,一般通过自动计划来完成。比如超时未发货、超时未鉴定、超时未同意退款、超时未履行对应服务等。3、admin:超级管理员主动发起的退款,一些特殊订单(售后纠纷、第三方投诉、涉及到法律纠纷)需要手动关闭订单并退款,那么就可以通过这个渠道来完成。
    5、新增退款方式字段【way】,退款钩子会根据这个字段来执行不同的拦截事件。1、如果值等于seller(卖家退款请求)则检测当前用户是否登录,如果未登录则返回【退款失败:请登录后操作】附带jump-login。如果已登录则检测支付订单数据是否存在【seller】字段,如果不存在或当前用户user_id与其不匹配则提示【退款失败:你无权操作】 2、如果值等于system(系统的退款行为)则检测是否存在refund_key,如果未传递则返回【退款失败:非法请求(系统拒绝)】,如果存在则继续与xc_pay_retund_key对比。不匹配则返回【退款失败:非法请求(参数无效)】。3、如果值等于admin(超级管理员退款),则通过xc_is_admin()来检测用户权限,如果不具备超级管理权则返回【退款失败:你的权限不足!】
    6、xc_payment_refund_hook钩子现在统一传递变量,移除原有的三个参数变量。改为传递统一数组变量【refund】,该数组必须传递的参数为:1、id支付表订单数据主键ID。2、amount支付金额。3、way:支付方式类型。4、remake:退款的备注说明,每个退款都需要提供这个参数来告知用户。这四个是必须的,其它的参数根据退款场景进行增加。统一数组结构,减少变量传递。
    7、发起统一订单退款时,会依次执行以下通用拦截:1、通过is_numeric检测支付金额是否为数字,如果不是则返回【退款失败:金额不是有效数字】。2、通过wpdb构建数据库查询,检索ID是否存在对应的主键ID记录,如果查询不到则返回【退款失败:支付订单不存在】。3、检索支付订单状态是否为refund,如果是则返回错误【退款失败:该订单已发起过退款<br>退款金额 (' . $payment['refund_amount'] . ' 元) 】。4、继续检测支付订单状态,如果不等于ok则返回错误【退款失败:支付订单状态不允许发起退款】。4、检测$refund['way']是否存在,如果不存在则返回【退款失败:参数缺失】。5、根据way值来执行不同的拦截事件。
    8、为了防止出现重复退款现象【非法请求或系统问题导致同时提交多个退款请求,造成并发执行退款函数】,特定增加一个redis并发锁机制,订单锁的标识:refund_' . $refund['id'],通过xc_lock函数进行上锁保护。锁的有效期为30秒。进行订单退款的时候,会先进行取锁动作,如果取锁失败会直接返回【退款失败:重复请求(订单锁)】,后续的退款业务逻辑会强制中止。
    9、统一退款保护机制:如果订单为B2C(商户订单、鉴定订单、淘货订单)类型,在进行退款前需要先检测订单状态是否已成交(订单款是否已转给卖家),如果已转给卖家,则本次退款需要从卖家手中进行扣款。需要检测卖家账户余额小于退款金额,那么需要做进一步处理。卖家主动退款的情况下会拦截,提示余额不足。如果是管理员或系统退款,则扣除账户保证金,或直接将账户余额标记为负数。防止完成退款后,系统倒贴这笔费用(如果大额订单,平台是无法承担损失)。
    10、账户余额保护机制:在宫论平台的交易过程中,账户余额保护机制旨在防止账户余额出现负数的情况。如果账户余额变为负数,用户将无法进行任何交易,直到通过充值将账户余额恢复为正数。在涉及退款、订单售后纠纷、平台处罚等场景时,账户余额可能会被扣款。如果用户的账户余额不足(例如,提前消费了金额并完成了提现),扣款操作将会失败。然而,平台仍需向买家进行打款结算,这意味着平台需要垫付资金,导致用户的账户余额变为负数。在这种情况下,用户必须先归还欠款,恢复账户余额为正数,才能继续进行交易。这样可以确保平台的资金安全。
    11、创建支付订单钩子:add_payment_order_hook增加一个保护拦截:在创建支付订单时,会通过get_user_meta来读取用户的money(账户余额)。如果存在(可能为空,需要跳过)并且余额数量小于0,则拦截本次订单创建请求,并返回错误提示【订单创建失败:账户余额为负数不允许交易<br>请先将账户余额恢复正常,在进行平台交易!】注:所有的支付请求,都需要通过这个钩子来创建,在创建订单时进行余额保护拦截,可以做到全局交易拦截。
    12、统一退款事件钩子,在发起退款前会主动验证退款金额【amount】数量,读取原支付订单表【pay_amount】字段。如果退款金额大于订单金额则返回错误【退款失败:退款金额大于支付金额】。同时增加一个验证,检查$refund['remake']变量是否存在,如果不存在返回错误【退款说明不得为空】。如果存在则通过xc_is_html进一步检测,如果返回tRUE则返回错误【退款备注信息不得包含HTML
    13、统一退款事件钩子现在能够正确处理【账户余额退款】,当发生退款请求时(基础),如果原订单是通过money完成支付的。则会调用xc_update_money_hook方法来进行退款操作。余额更新标识为refund,订单号为支付订单表的主键ID值,退款金额由refund[amount]提供。余额更新返回结果会赋值到update_money,如果其结果code=1则说明余额更新失败,此时会直接返回原错误代码,拒绝后续的代码执行。如果执行成功则调用xc_update_sql方法来更新支付订单表,更新的内容包括【state:订单状态标记为refund、refund_order:通过xc_order函数随机生成、refund_amount:本次结算的退款金额数值、refund_time:当前的时间日期。return_content:退款的描述信息。】返回code=0。完成余额退款动作。
    14、新增后端钩子:xc_payment_refund_ok_hook()当支付订单发生退款,并且成功的情况下会触发。该钩子需要传递refund数组变量【包括way:退款类型,一般分管理员/卖家/系统、id:支付订单记录表、amount:退款金额数值、remake:退款说明信息】。钩子没有返回信息,属于预留事件。如果退款成功需要进行一些交互通知,可以通过这个钩子来执行。
  • 0
    小小乐lv.2实名用户
    2024年07月4日
    1、修复一个致命性问题,通过支付宝付款的订单在完成付款后支付类型会变为:aliapy,正确的标识应当为:alipay。这个错误标识导致支付订单类型出现错误。经过日志跟踪发现问题是由于支付宝订单回调接口【alipay_callback.php】在接收到支付订单数据后,写入payment数组时,将pay_select写成【aliapy】。这个数组后面会进行sql更新,这也导致支付类型来源出现错误。
    2、支付宝订单查询结构已完成构建,如果SDK成功返回信息首先回通过toArray将结果转为数组。然后对返回结果trade_status进行判断处理,根据这个字段来返回不同的错误。1、WAIT_BUYER_PAY:查询结果:订单等待付款中。2、TRADE_CLOSED:查询结果:订单已被关闭。3、不等于【TRADE_SUCCESS、TRADE_FINISHED】:查询结果:订单未完成支付(其它错误)。注:TRADE_SUCCESS代表订单完成付款、TRADE_FINISHED代表订单交易结束,不可退款。两者都可以判断为已付款。
    3、修复微信支付订单查询一个判断书写错误,当通过Pay::wechat()->query查询支付订单时候,会通过Pay::wechat()->query方法去获取订单状态和结果,并将结果存储到【result_array】。这里为了确保响应结果存在,会使用is_array去检查result_array是否为数组,并通过issest检查数组中是否存在$result_array['trade_state']。这里的判断使用了&&,同时符合条件才生效。这直接导致这个安全检测失效。已进行错误修正处理。
    4、支付宝订单完成状态验证后,会获取支付金额【total_amount:交易的订单金额,单位为元,两位小数。该参数的值为支付时传入的total_amount】然后与订单支付表的pay_amount进行判断。如果不一致则直接返回错误【查询结果:支付金额与订单金额不一致<br>请联系管理员处理】。如果一致则在支付订单基础上加上三个字段【code=0 标记支付成功、msg:查询结果:支付宝账单已付款、payment:返回支付宝官方的查询信息数组,方便后续的查询】
    5、宫论统一支付订单查询接口已完成封装:xc_hook_payment_query该接口支持三种来源查询。1、账户余额查询,直接通过xc_pay数据表来返回查询结果。2、wxpay:微信支付订单查询,通过调用统一支付SDK,请求微信官方返回订单结果。3、alipay:支付宝订单查询,通过统一支付SDK,请支付宝官方返回订单结果。支持三种订单查询【ID;支付订单ID主键、pay_order:对应支付平台的支付订单、payment_order:商户订单号】,钩子内部会自动解析查询数据表,并根据支付类型调用对应的查询。该接口会做各种安全检测,确保本次查询结果是安全可靠的。注:统一支付代表所有订单都会通过同一接口来完成支付,那么查询接口也是统一的。查询的订单必须是在支付订单数据表中,如果不存在则默认返回错误。注2:该接口作用于,查询某个订单是否已完成付款。采用SDK请求支付服务商来验证结果,非常安全可靠!
    6、后端增加一个接口:xc_close_sdk_payment_hook($id),该钩子需要传递支付订单数据表主键ID,返回标准的数组结构,code=0代表处理成功,code=1代表处理失败。该钩子作用于,当订单发生关闭请求时(系统超时关闭,用户主动关闭订单、卖家主动关闭订单)会检索订单付款请求是否为wxpay微信支付、alipay支付宝支付。如果是为了防止用户手机端二次进行支付,需要通过SDK发起订单关闭请求。
    7、考虑到二次进行sql查询有些影响性能,SDK关闭支付订单接口,现在不在要求传递【id:支付订单数据表主键】,而是要求直接提供out_trade_no:【商户订单号】 商户系统内部订单号。该字段在关闭订单统一事件中通过payment数组直接提取即可。避免sdk钩子二次读取数据库,同时增加第二个变量type:支付来源。固定值为wxpay、alipay。需要根据这个参数来决定发送不同的SDK请求
    8、订单关闭接口会进行三个初始化动作。1、初始化result变量,将其设置为空数组。后续无论是否关闭成功都会通过这个数组返回信息。2、使用require_once获取到统一支付SDK,无论是微信支付还是支付宝都需要通过这个SDK来发起订单关闭请求。3、使用xc_payment_config_hook方法来获取SDK所需要的配置信息参数,并将其赋值到config。
    9、升级统一支付SDK【yansongda/pay】3.7.4-3.7.7。通过composer update命令完成升级。本次SDK升级主要修复以下bug:1、微信关闭订单报解包错误的问题(#1000, #1001)。2、支付宝响应空签名时签名验证逻辑错误的问题(#998)。3、优化微信 ResponsePlugin 插件去除不必要的返回参数(#996)。4、deprecate: 微信 StartPlugin 改为使用 yansongda/artful 中的插件(#993)。注:版本升级,需要记录版本号,如果出现问题 需要及时回滚处理。
    10、微信订单关闭接口完成封装,当关闭接口收到【wxpay】请求,会调用 \Yansongda\Pay\Pay::wechat()->close方法来关闭订单,并使用try-catch来捕获各种错误异常,如果因为【支付网关、无效参数、签名异常、其它问题】造成的关闭失败,会直接返回错误,并终止执行。如果一切正常,则会返回code=0,完成订单支付功能。注:微信支付订单关闭接口疑似存在一些问题,需要重点监听。官方在订单关闭后,不会有任何返回。
    11、xc_close_payment_skd_hook已支持支付宝订单关闭请求,需要传递ID:商户单号和查询类型:alipay。函数内会调用\Yansongda\Pay\Pay::alipay()->close($order)方法来发起查询,order是封装的查询对象,主要参数为【商户订单号】。返回的结果会赋值到【query_result】,然后对进行toArray处理,确保返回的结构体为数组。后续需要接收数组参数来确定结果。
    12、调用pay::alipay()->close方法关闭支付订单时,会使用try-catch来捕获异常。目前已监听以下场景,发行错误会返回code=1,并返回对应的错误信息。1、GatewayException(支付网关出现异常时触发)。2、InvalidArgumentException(提交的参数存在无效情况触发)。3、InvalidSignException(签名或验签过程出现异常时出发)。4、Exception通用其它异常错误返回,一般为SDK的构造体返回异常。
    13、支付宝关闭订单时,会对返回结构进行二次检查。如果ACQ返回:INVALID_PARAMETER则返回参数无效。REASON_ILLEGAL_STATUS:返回交易订单异常。SYSTEM_ERROR:返回系统异常。TRADE_NOT_EXIST:返回交易不存在。TRADE_STATUS_ERROR:返回交易状态不合法。如果上述拦截都跳过,则判断订单关闭成功。注:支付宝订单大部分场景都会视为TRADE_NOT_EXIST,因此关闭订单不代表可以拦截用户付款。
    14、xc_close_payment_hook在执行订单关闭请求时,会验证支付订单是否来源于:alipay支付宝和wxpay微信的支付订单。如果是则会触发xc_close_payment_sdk_hook钩子来关闭订单付款请求。防止订单被关闭后,用户仍旧可以通过界面来发起支付请求。注:该接口存在一个瑕疵需要特别注意:支付宝用户未完成付款的情况下,通过该接口发起关闭,会显示订单不存在。官方描述是,只有用户输入密码才会创建订单。匪夷所思的设计,需要联系官方进一步确认。
  • 加载更多评论
    单栏布局 侧栏位置: