支付宝个人收款解决方案之支付宝签约方案(代码片段)

asmcvc asmcvc     2022-12-07     499

关键词:

关键词:签约支付,签约收款,支付宝收款,个人签约收款

背景

​ 有做网赚或者在网上售卖个人小产品小服务的,需要进行收款,如果零星个别的收款可能直接走个人转账然后手动发货即可,但是一旦流程标准下来,量走起来之后,付款发货就需要自动化了,以提高人效。例如在网站上挂一个购买链接,用户点击后自动展示收款码,用户扫码付款后网站自动完成发货,是不是感觉很好?或者在APP里提供了付费功能,用户需要购买的时候,能够直接弹出支付宝(或微信)付款,完成付款后自动提供付费功能,是不是感觉很好?

​ 本方案场景是针对「个人开发者」或其他「个人商家」的,后面简称个人收款方案。对于已经拥有公司的,直接签约支付宝或微信的支付功能即可。

​ 个人收款总结下来有两类:签约免签约

  • 签约方案就是直接和支付宝或者微信签约,严格按照支付宝或微信的要求一步步来,完成签约后使用它们的官方接口即可。该方案比较稳定,但是如果售卖的商品属于灰色的话,很容易被「风控」禁用,毕竟使用的是人家的服务,很容易被管控。早期的时候可以直接个人签约,但是后来就不行了,个人必须用营业执照才行。
  • 免签约方案就是避开使用支付宝或微信的签约流程,自己搭建一套支付收款体系,这个在下一篇文章中再做介绍。

​ 网上有很多集成了收款方案做的聚合收款方案,大家可以了解,但是这些大多是属于不正规的个人或小团队搭建的,因为涉及到资金汇款,这个风险很高,不建议实际使用。截止到目前为止,以前做调研收集到的一些网站已经打不开了,收集了一些权当做了解、借鉴、参考,后面专门整理一篇文章介绍下。

今天主要介绍签约方案,以APP收款为例介绍,即假设你开发了一款需要用户付费的APP,有收款场景。支付方式以支付宝为例介绍,微信方案同理。

方案

​ 目前个人签约收款,需要营业执照,个人的话可以申请个体工商户,自己跑腿办理也可以,或者直接找某宝上找代办也可以。现在个体工商户的注册也需要线下实体门店对应,杭州地区的价格比较高需要3000块,某宝代理办了个外地的,200块就搞定了,流程测完跑通后又花100块让代办注销掉了,怕以后出麻烦。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FTcGt5DY-1626589011082)(…/…/images/payMethod/commercial.png)]

​ 如果仅仅是学习研究,可以使用支付宝提供的「沙箱模式」,可以认为是测试环境,跑通流程即可。如果是真实需要支付收款,可以先把营业执照申请起来(需要时间),一边使用沙箱模式开发,它可以让我们不具备这些应用或者说应用审核还没通过的时候先开发调试。

沙箱模式

参考:

登录支付宝网页版,点击“开放平台-开发者中心-沙箱环境”。下载沙箱钱包(也就是测试用的支付宝App):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4b7GxaAb-1626589011085)(…/…/images/payMethod/sandboxAppDown.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z1JN5kvF-1626589011098)(…/…/images/payMethod/sandboxApp.png)]

使用签名工具创建密钥:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-91vexqxH-1626589011102)(…/…/images/payMethod/signToolGenPublicKey.png)]

因为是Android应用,选择PKCS8(JAVA适用),点击生成密钥,复制公钥,然后到沙箱应用中,设置一下这个公钥:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WTPdthkm-1626589011105)(…/…/images/payMethod/setPublicKey1.png)]

选择公钥,然后把公钥粘贴进来,最后保存设置。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TNwMogiL-1626589011108)(…/…/images/payMethod/setPublicKey2.png)]

把沙箱应用的appid记下来,例如此处是:2021102200872184

在Android的demo里修改代码:

1、设置沙箱模式:

protected void onCreate(Bundle savedInstanceState) 
   EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);
   super.onCreate(savedInstanceState);
   setContentView(R.layout.pay_main);

2、设置APPID,2021102200872184

3、设置私钥,这个demo是直接把私钥写死代码里的,直接把上一步使用签名工具生成的私钥复制下来,贴到RSA2_PRIVATE

编译运行demo,点击“支付宝支付demo”:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TyHlcTka-1626589011110)(…/…/images/payMethod/sandboxAppUI.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lkRhTyxX-1626589011112)(…/…/images/payMethod/sandboxAppStartPay.png)]

登录使用沙箱账号的买家账号进行支付:

(这一步是为了登录网页版查看测试用的买家账号的)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xSxUXKWx-1626589011113)(…/…/images/payMethod/sandboxBuyerAccount.png)]

继续支付:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yx1wbFoM-1626589011115)(…/…/images/payMethod/sandboxAppPay1.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KCpsXtVE-1626589011117)(…/…/images/payMethod/sandboxAppPay2.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oIYPBRui-1626589011118)(…/…/images/payMethod/sandboxAppPay3.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5W3HlBjV-1626589011120)(…/…/images/payMethod/sandboxAppPay4.png)]

调试跟踪数据:

"app_id" -> "2021102200872184"
"timestamp" -> "2016-07-29 16:55:53"
"biz_content" -> ""timeout_express":"30m","product_code":"QUICK_MSECURITY_PAY","total_amount":"0.01","subject":"1","body":"我是测试数据","out_trade_no":"1012152245-1761""
"method" -> "alipay.trade.app.pay"
"charset" -> "utf-8"
"version" -> "1.0"
"sign_type" -> "RSA2"
"app_id" -> "2021102200872184"
"timestamp" -> "2016-07-29 16:55:53"
"biz_content" -> ""timeout_express":"30m","product_code":"QUICK_MSECURITY_PAY","total_amount":"0.01","subject":"1","body":"我是测试数据","out_trade_no":"101215243516617""
"method" -> "alipay.trade.app.pay"
"charset" -> "utf-8"
"version" -> "1.0"
"sign_type" -> "RSA2"
app_id=2021102200872184&timestamp=2016-07-29+16%3A55%3A53&biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%221012152245-1761%22%7D&method=alipay.trade.app.pay&charset=utf-8&version=1.0&sign_type=RSA2&sign=GXgsKV3Hb0SrOHE%2FtempExxFFnomjUJHu1ZQOpd8JSk6NXnVy2I4FKVFPO0h8JNdnruZst2CZXUPnnkgVs5mmXSJA3IZQuQO4M%2FnTvEhNACzyxQkNhqLlAiAePXMt5bHqUlDDciDgQGdzpKfm2iIjNxS76b%2FJIFmkX85PMrcbrUNnhzokjq52Qb9wbLCh5GOxxxxxxxxxxxxxxxxxxxxqdsQmiqbhi0V8pW5lWF3weIF6E0aw%3D%3D
app_id=2021102200872184&timestamp=2016-07-29+16%3A55%3A53&biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%221012152245-1761%22%7D&method=alipay.trade.app.pay&charset=utf-8&version=1.0&sign_type=RSA2&sign=GXgsKV3Hb0SrOHE%2FtempExxFFnomjUJHu1ZQOpd8JSk6NXnVy2I4FKVFPO0h8JNdnruZst2CZXUPnnkgVs5mmXSJA3IZQuQO4M%2FnTvEhNACzyxQkNhqLlAiAePXMt5bHqUlDDciDgQGdzpKfm2iIjNxS76b%2FJIFmkX85PMrcbrUNnhzokjq52Qb9wbLCh5GOxxxxxxxxxxxxxxxxxxxxqdsQmiqbhi0V8pW5lWF3weIF6E0aw%3D%3D

代码

使用的是支付宝SDK:

implementation files('libs/alipaySdk-20180403.jar')

支付页面的代码:

public class BuyVipActivity extends BaseActivity 
    private static final int MSG_GET_RECOVERHISTORY_SUCCESS = 555;
    private static final int MSG_GO_PAY_STATE_ACTIVITY = 387;
    private static final int MSG_LOAD_VIP_COMPLETE = 37;
    private static final int MSG_LOCAL_PAY_ERROR = 430;
    private static final int MSG_PAY_FAILED = 710;
    private static final int MSG_PAY_STOP_GET_PAY_INFO = 590;

    // 滚动数据:用户付费记录
    private LooperTextView looperTextView;
    private List<String> looperNotice;

    // VIP类型列表
    private RecyclerView rvVipList;

    // 付费价格
    private TextView tvPrice;

    // 联系手机
    private EditText etContactPhone;

    // 确认支付按钮
    private TextView tvbtnPay;

    private int productTypeNo = ProductTypeEnum.UNKOWN.getTypeno();
    private VipListAdapter vipListAdapter;

    protected int getLayoutId() 
        return R.layout.activity_buy_vip;
    

    protected void initView() 
        super.initView();
        setToolbarTitle("订单支付").setToolbarLeftIcon(R.drawable.ic_arrow_back_white);
        this.etContactPhone = findViewById(R.id.etContactPhone);
        this.tvbtnPay = findViewById(R.id.tvbtnPay);
        this.tvPrice = findViewById(R.id.tvPrice);
        this.looperTextView = findViewById(R.id.looperTextView);
        this.vipListAdapter = new VipListAdapter();
        this.vipListAdapter.setOnVipSelectChangedListener(new OnVipSelectChangedListener() 
            public void onVipSelectedChanged(ProductData vipItemData) 
                tvPrice.setText("¥" + vipItemData.getCurrentprice());
            
        );
        this.rvVipList = findViewById(R.id.rvVipList);
        this.rvVipList.setLayoutManager(new LinearLayoutManager(this));
        this.rvVipList.setAdapter(this.vipListAdapter);
        showProgressDialog();
        this.tvbtnPay.setOnClickListener(v -> onPayClick());
        this.productTypeNo = getIntent().getIntExtra("producttypeno", ProductTypeEnum.UNKOWN.getTypeno());
        if (this.productTypeNo == ProductTypeEnum.UNKOWN.getTypeno()) 
            finish();
        
    

    protected void onResume() 
        super.onResume();
        loadVipList();
        getRecoverHistory();
    

    // 从服务端获取VIP类型
    public void loadVipList() 
        ThreadUtil.runOnMulti(() -> postUIMessage(MSG_LOAD_VIP_COMPLETE, 0, 0, HttpManager.getProducts(productTypeNo)));
    

    public void processUIMessage(Message message) 
        super.processUIMessage(message);
        int msgWhat = message.what;
        if (msgWhat == MSG_LOAD_VIP_COMPLETE) 
            DataResponse<List<ProductData>> vipList = (DataResponse) message.obj;
            if (vipList.isOk()) 
                this.vipListAdapter.setList(vipList.getData());
                if (vipList.getData().size() > 0) 
                    this.vipListAdapter.selectItem(0);
                    this.tvPrice.setText("¥" + vipList.getData().get(0).getCurrentprice());
                
             else 
                showToast(vipList.getMessage());
            
            dismissProgressDialog();
         else if (msgWhat == MSG_GO_PAY_STATE_ACTIVITY) 
            Bundle data = message.getData();
            NavigateUtil.goOrderStatusActivity(AppApplication.getContext(), data.getString(c.e), data.getFloat("price"), data.getString("payorderno"));
            finish();
         else if (msgWhat == MSG_LOCAL_PAY_ERROR) 
            String resultMsg = String.valueOf(message.obj);
            dismissProgressDialog();
            showToast(resultMsg);
         else if (msgWhat == MSG_GET_RECOVERHISTORY_SUCCESS) 
            if (looperNotice == null || looperNotice.isEmpty()) 
                this.looperTextView.setTipList(null);
             else 
                this.looperTextView.setTipList(looperNotice);
            
         else if (msgWhat == MSG_PAY_STOP_GET_PAY_INFO) 
            dismissProgressDialog();
         else if (msgWhat == MSG_PAY_FAILED) 
            showToast(String.valueOf(message.obj));
        
    

    // 正在获取订单信息...
    public void showDlgGetOrderInfo() 
        showProgressDialog("", getResources().getString(R.string.tip_getting_order_info));
    

    public void stopDlgGetOrderInfo() 
        postUIMessage(MSG_PAY_STOP_GET_PAY_INFO);
    

    // 确认支付
    public void onPayClick() 
        String phone = this.etContactPhone.getText().toString().trim();
        if (TextUtils.isEmpty(phone)) 
            showToast("请填写联系方式!");
            return;
        
        if (phone.length() > 14) 
            phone = phone.substring(0, 14);
        
        ProductData vipType = this.vipListAdapter.getSelectedItem();
        if (vipType == null) 
            showToast("请您选择其中一项进行支付.");
            return;
        

        // 正在获取订单信息...
        showDlgGetOrderInfo();

        final String contactNumber = phone;
        ThreadUtil.runOnMulti(new Runnable() 
            @Override
            public void run() 
                // 从服务器获取订单信息
                DataResponse<PayData> payData = HttpManager.getPayData(vipType.getProductSku(), contactNumber, PayEnum.ALIPAY, getPayDesc());
                stopDlgGetOrderInfo();
                if (!payData.isOk()) 
                    postUIMessage(MSG_PAY_FAILED, 0, 0, payData.getMessage());
                    return;
                

                // 调用支付宝SDK支付
                String payOrderNo = payData.getData().getPayorderno();
                PayResult payResult = new PayResult(new PayTask(BuyVipActivity.this).payV2(payData.getData().getPayorder(), true));
                /*payResult的返回内容:
                resultStatus=6001;memo=用户取消;result=
                 */
                String resultStatus = payResult.getResultStatus();
                if (TextUtils.equals(resultStatus, PayStateEnum.PAY_STATE_USER_CANCEL.getPayStateNo() + "")) 
                    onPayError(PayStateEnum.PAY_STATE_USER_CANCEL.getPayStateDesc());
                 else if (TextUtils.equals(resultStatus, PayStateEnum.PAY_STATE_NET_ERROR.getPayStateNo() + "")) 
                    onPayError(PayStateEnum.PAY_STATE_NET_ERROR.getPayStateDesc());
                 else if (!BuyVipActivity.this.redirecting.getAndSet(true)) 
                    Bundle data = new Bundle();
                    data.putString(c.e, vipType.getName());
                    data.putFloat("price", vipType.getCurrentprice());
                    data.putString("payorderno", payOrderNo);
                    postUIMessage(MSG_GO_PAY_STATE_ACTIVITY, data);
                
            
        );
    

    public void onPayError(String resultMsg) 
        ThreadUtil.runOnMulti(new Runnable() 
            @Override
            public void run() 
                try 
                    Thread.sleep(1000);
                 catch (InterruptedException e) 
                    e.printStackTrace();
                

                DataResponse<VipInfoData> responseBean = HttpManager.getVipInfo();
                if (responseBean.isOk()) 
                    CacheUtil.setVipInfo(responseBean.getData());
                
            
        );

        postUIMessage(MSG_LOCAL_PAY_ERROR, 0, 0, resultMsg);
    

    private String getPayDesc() 
        StringBuilder buffer = new StringBuilder();
        if (PublicUtil.checkApkExist("com.eg.android.AlipayGphone"查看详情  

支付宝个人收款解决方案之支付宝签约方案(代码片段)

关键词:签约支付,签约收款,支付宝收款,个人签约收款背景​有做网赚或者在网上售卖个人小产品小服务的,需要进行收款,如果零星个别的收款可能直接走个人转账然后手动发货即可,但是一旦... 查看详情

微信支付宝个人收款解决方案之免签约支付解决方案之app监控通知方案(代码片段)

关键词:免签约支付,免签约收款,支付宝收款,微信收款,个人免签约收款背景​有做网赚或者在网上售卖个人小产品小服务的,需要进行收款,如果零星个别的收款可能直接走个人转账然后手动发... 查看详情

微信支付宝个人收款解决方案之免签约支付解决方案之app监控通知方案(代码片段)

关键词:免签约支付,免签约收款,支付宝收款,微信收款,个人免签约收款背景​有做网赚或者在网上售卖个人小产品小服务的,需要进行收款,如果零星个别的收款可能直接走个人转账然后手动发... 查看详情

微信支付宝个人收款解决方案之免签约支付解决方案之app监控通知方案(代码片段)

关键词:免签约支付,免签约收款,支付宝收款,微信收款,个人免签约收款背景​有做网赚或者在网上售卖个人小产品小服务的,需要进行收款,如果零星个别的收款可能直接走个人转账然后手动发... 查看详情

个人收款解决方案之三方聚合收款方案

关键词:签约支付,签约收款,支付宝收款,个人签约收款背景​有做网赚或者在网上售卖个人小产品小服务的,需要进行收款,如果零星个别的收款可能直接走个人转账然后手动发货即可,但是一旦... 查看详情

个人收款解决方案之三方聚合收款方案

关键词:签约支付,签约收款,支付宝收款,个人签约收款背景​有做网赚或者在网上售卖个人小产品小服务的,需要进行收款,如果零星个别的收款可能直接走个人转账然后手动发货即可,但是一旦... 查看详情

个人收款解决方案之三方聚合收款方案

关键词:签约支付,签约收款,支付宝收款,个人签约收款背景​有做网赚或者在网上售卖个人小产品小服务的,需要进行收款,如果零星个别的收款可能直接走个人转账然后手动发货即可,但是一旦... 查看详情

搭建免签约支付系统需要什么技术?

...的行业,但是如何收款是这些个人站长一直存在的问题,支付宝与微信目前对网站的接入要求审核都比较严格需要一些硬性的资质才能申请,并且对接入网站的内容也有严格的要求,那么要是站长们没有资质,要怎么解决收款的... 查看详情

xddpay.com个人支付接口接入流程(代码片段)

作为一个独立开发者产品需要支付接口是挺麻烦的,支付宝微信都不对个人开放,注册公司维护成本太高,市面上各种收款工具要么手续费太高,要么到账很慢,体验很不好。看到「小叮当支付」这个收款工具,挺有意思的。原... 查看详情

vue支付宝支付笔记总结(代码片段)

...于为企业和个人提供“简单、安全、快速、便捷”的支付解决方案。支付宝公司从2004年建立开始,始终以“信任”作为产品和服务的核心。旗下有“支付宝”与“支付宝钱包”两个独立品牌。自2014年第二季度开始成为当前... 查看详情

微信支付宝xposed个人收款免签支付源码

源码介绍:    个人免签支付是指使用自己的微信支付宝账号作为个人网站的收款账号,网站订单支付成功后,网站能实时收到成功回调信息。    系统基于xposed逆向微信、支付宝、云闪付来实现个人... 查看详情

c#版支付宝手机网站支付接口api之(转)(代码片段)

C#版支付宝手机网站支付接口API之2018年03月03日15:59:25 liutong123987 阅读数:3072 2018年03月03日15:59:25 liutong123987 阅读数:3072 支付宝手机网站支付接口API之C#版 一、准备工作1、使用企业支付宝签约手机网站... 查看详情

pc软件/web网站/小程序/手机app产品如何增加个人收款接口

...通过 XorPay 注册个人收款接口,原理是帮助你签约支付宝和微信(不需要营业执照)支持个人支付宝和个人微信支付接口,大概几分钟可以开通,开通后即可永久使用PC网站接入效果:用户点击支付后,前端ajax请求你的后... 查看详情

支付宝代签约当面付支付(代码片段)

?:官方文档?:调用接口alipay.trade.create(统一收单交易创建接口) 首先创建应用 步骤:蚂蚁金服开放平台-->开发中心-->第三方应用    开发配置  添加功能(当面付,获取会员信息,第三方应用授权... 查看详情

支付宝免签,个人支付宝,自动转账,自动提现到银行卡,自动银行卡转账

微信,支付宝,收款二维码实时生成订单监控,免签支,付支付系统,个人收款,收款二维码微信和支付宝个人支付二维码生成与监控!有PHP接口回调,个人收款好助手!实现收款即时到个人微信或支付... 查看详情

企业支付宝签约当面付显示“系统综合评估签约条件不满足,谢谢你的支持”怎么解决?

企业支付宝要绑定银行对公账户。商家认证必须要使用和公司名称一致的对公账户,暂不支持个人银行卡。如有疑问,建议您联系支付宝官方客服进行咨询。温馨提示:以上内容仅供参考。应答时间:2022-01-17,最新业务变化请... 查看详情

支付宝周期扣款(代码片段)

...该问题)应用私钥和证书一定要弄对不然很麻烦想看支付宝接口情况 https://opensupport.alipay.com/support/too 查看详情