【3種類まとめ】vueプロジェクト【H5】バックエンドから返されるAlipayフォームをどう処理し、ペイメントジャンプを実現するには?

背景:現在のすべてのプロジェクトには支払いが必要であり、必然的に Alipay または WeChat 支払いが必要になります。Alipay の支払いの場合、2202 年が経過したと多くの人が言いますが、Alipay は依然としてフォーム form を返し、その後 Alipay インターフェイスを呼び出します。
    一般的に、Alipay はフロントエンドで開始される支払いとバックグラウンドで開始される支払いの 2 つのタイプに分けられます。
① フロントエンドで開始される支払い、まず注文データをバックグラウンドに送信して注文を生成します。次に、フロントエンドが携帯電話の支払いを呼び出して支払いを行います、
②バックグラウンドで支払いを開始する方法が採用されている場合、戻り値は、< script > を含む < form >< /form > のフォーム HTML 構造になります。 「送信ボタン イベントをリッスンする」</script> タグで書かれています。
簡単に言うと、バックグラウンドで開始された支払いはフォーム フォームを返し、フォーム内の submit メソッドが呼び出されて、Alipay インターフェイスが呼び出されます。

1. 実装アイデア

    まず、ビジネス ロジックを明確にします。支払いジャンプの前に注文情報を送信するプロセスが [post] に必要であり、支払いフォーム全体が [post] 後に結果を返します。返される文字列の結果は次のようになります。
ここに画像の説明を挿入

ここに画像の説明を挿入
支払いプロセス全体を整理すると、次のとおりです (このプロセスは会社のビジネスのみに適用されます。参考までに)。
①トークンを生成し、createToken;
②注文 createOrder を作成し、orderCoder を生成します (追記: 後で注文の詳細を取得するためにこれを使用する必要があります);
③ H5が post インターフェイスを通じて呼び出され、フォーム form を返します(インターネット上のほとんどのケースはこのステップを指します)。
④H5 とステップ③は同時に開始され、注文の詳細を取得して支払い結果をポーリングし、最後に支払い成功または支払い失敗の結果を返します (追記: このプロセスでは、バックグラウンドでフロントエンドが呼び出され、支払い後のコールバック。現在、バックグラウンド支払いを状態へのインターフェイスと呼ぶためにポーリングが使用されています)。

2. 関連コード

フロントエンド関連のコード:
2.1 方法一:使用document.forms[0].submit(),提交表单操作
(1) まず、フォームのコンテンツをページに配置します。

<div class="aliform" v-html="aliform"></div>

(2) document.forms[0].submit() を通じて現在のページの最初のフォーム送信を取得します。

<script>
export default {
    
    
	data() {
    
    
	    return {
    
    
	      aliform: "",
	    };
  	},
  	methods: {
    
    
		async iosAlipay(orderCode) {
    
    
      		let data = await requestAlipay(orderCode);
      		if (data.code == 20000) {
    
    
        		this.aliform = data.data;  //data.data就是支付宝返回给你的form,获取到的表单内容,具体样子可见上面的图片
        		this.$nextTick(() => {
    
    
        			// 获取订单详情来轮询支付结果
          			this.getOrderDetail();  
          			console.log(document.forms);  //跳转之前,可以先打印看看forms,确保后台数据和forms正确,否则,可能会出现一些奇奇怪怪的问题 ╮(╯▽╰)╭
          			document.forms[0].submit();  //重点--这个才是跳转页面的核心,获取第一个表单并提交
        		});
      		}
    	},
    	// 轮询结果
	    getOrderDetail() {
    
    
	    //轮询方法,因为支付是跳转到第三方支付宝,我们无法获知用户是否支付成功,或者用户支付成功后是否跳转回来。轮询方法,在一定时间内
	      clearTimeout(this.timer);
	      this.timer = setTimeout(() => {
    
    
	        let initTime = +new Date();
	        let loop = () => {
    
    
	          getOrderDetail({
    
     orderCode: this.orderCode}).then((res) => {
    
    
	            if (res.code == 20000 && res.data && res.data.payStatus == 30) {
    
    
	              //支付成功的相关操作
	            } else {
    
    
	              let now = +new Date();
	              if (now - initTime < 45000) {
    
    
	                loop();
	              } else {
    
    
	                // 超时按照失败处理
	                //支付失败的结果
	              }
	            }
	          });
	        };
	        loop();
	      }, 500);
	    },
	}
}
</script>
<style lang="less" scoped >
.aliform {
    
    
  width: 1px;
  height: 1px;
  opacity: 0;
}
</style>

(3) 余談 – js によって提供される document.forms メソッドを見てください。

(1)document.forms //表示获取当前页面的所有表单;
(2)document.forms[0] //表示获取当前页面的第一个表单;
(3)document.forms['exportServlet'] //表示获取当前页面的name="exportServlet"的表单
(4)submit() //表示提交函数

2.2 方法二:使用document.write(),就是重定向,覆盖原始页面

\\ 假设result是后端返回的from字符串
const newWindow = window.open('', '_self');  
newWindow.document.write(result);
newWindow.focus();

また、直接使用document.write(xxx),来进行支付跳转

await postUserinfo('接口入参').then(res=>{
    
    
	document.write(res.data.result)
})

PC側で処理する場合はこの方法でも問題ありませんが、次の3点に注意が必要です。
①window.open() はインターフェイスのコールバックでトリガーされ、ブラウザによってインターセプトされる可能性があります;
②ページ自体のアドレスが https で、返されたフォームのアクションが http の場合、ブラウザはセキュリティ プロンプトもポップアップ表示します;
③WeChat環境ウィンドウ.open()は効果がありません。
2.3 方法三:动态创建div容器,将form渲染进去,js触发form提交
結果として返されるフォームの外側に html パッケージがありますが、動的に div コンテナを作成すると、<html> を含む結果がその中にレンダリングされ、js を通じてフォームの送信がトリガーされます。

const div = document.createElement('formdiv');
div.innerHTML = result;
document.body.appendChild(div);
document.forms['cashierSubmit'].setAttribute('target', '_self');
document.forms['cashierSubmit'].submit();
div.remove();

H5 の場合、このソリューションはより互換性があります。注意しなければならないことは次のとおりです。
当初、フォームのターゲットを _blank に設定すると、ios 上のブラウザ (WeChat 環境、safari、UC) からフォームフォームを送信できなくなりました。_self に変更すると問題は解決します。

あるいは、次のようにすることもできます。

let divForm = document.getElementsByTagName('divform')
if (divForm.length) {
    
    
    document.body.removeChild(divForm[0])
}
const div = document.createElement('divform')
div.innerHTML = res.data // res.data就是支付宝返回给你的form
document.body.appendChild(div)
// document.forms[0].setAttribute('target', '_blank') // 加了_blank可能出问题所以我注释了
document.getElementById('alipay_submit').submit()

または、これを試してください:

 //将接口返回的Form表单显示到页面
 document.querySelector('body').innerHTML = res.data; // res.data就是支付宝返回给你的form
 //调用submit 方法
 document.forms[0].submit()

参考ブログ:

UNI-APP は Alipay から返された FORM フォームを解析し、Alipay インターフェイスを呼び出します https://www.freesion.com/article/6241970398/
Vue は Alipay から返されたフォームの問題を完全に解決します。これが最も効果的な解決策である可能性があります https:// blog .zixutech.cn/archives/324
vue プロジェクトのバックエンドによって返される Alipay フォーム、支払いのジャンプを実現するにはどうすればよいですか? https://blog.csdn.net/qq_45934004/article/details/126156546
Vue がフォームフォームを自動的に送信した後、自動的にサードパーティのページにジャンプします https://www.jianshu.com/p/e2323b4e2cf9
の開発ノートuniapp Alipay 支払い返品フォーム フォーム ソリューション http://blog.haiya360.com/archives/766.html
vue Alipay 返品 URL 新しいウィンドウが開きます https://blog.csdn.net/wax9092/article/details/86631151
H5 処理 Alipay インターフェイス返信フォーム https://www.jianshu.com/p/8c5375671495
vue プロジェクトのバックエンドによって返される Alipay フォーム、支払いのジャンプを実現するにはどうすればよいですか? https://blog.csdn.net/qq_45934004/article/details/126156546
Vue は、Alipay から返されたフォームの問題を完全に解決します。これが最も効果的な解決策である可能性があります。 https://blog.zixutech.cn/archives/324

おすすめ

転載: blog.csdn.net/qq_26780317/article/details/126605149