微信支付H5调用支付详解(java版)_java

最近项目需要微信支付,然后看了下微信公众号支付,,虽然不难,但是细节还是需要注意的,用了大半天时间写了个demo,并且完整的测试了一下支付流程,下面分享一下微信公众号支付的经验。

一、配置公众号微信支付 

需要我们配置微信公众号支付地址和测试白名单。

比如:支付JS页面的地址为 http://www.xxx.com/shop/pay/

那此处配置www.xxx.com/shop/pay/

二、开发流程

借用微信公众号支付api(地址 http://pay.weixin.qq.com/wiki/doc/api/index.PHP?chapter=7_4),我们需要开发的为红色标记出的。如下:

三、向微信服务器端下订单

调用统一下单接口,这样就能获取微信支付的prepay_id(http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_1)。

在调用该接口前有几个字段是H5支付必须填写的openid

3.1 获取openid

可以通过网页授权形式(http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html)

在微信中发送如下链接
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=要跳转的下订单的url&response_type=code&scope=snsapi_base&state=123#wechat_redirect

3.2 下订单获取prepay_id

代码如下,实际上是通过post发送一个xml 文件,获取微信服务器端发送过来的prepay_id。

import java.io.ByteArrayInputStream;
import javaioIOException;
import javaioInputStream;
import javaioUnsupportedEncodingException;
import javautilDate;
import javautilHashMap;
import javautilIterator;
import javautilMap;
import javautilMapEntry;
import javautilRandom; 

import javaxservlethttpHttpServletRequest;
import javaxservlethttpHttpServletResponse; 

import orgapachecommonscodecdigestDigestUtils;
import orgspringframeworkstereotypeController;
import orgspringframeworkwebbindannotationRequestMapping;
import orgxmlpullvXmlPullParser;
import orgxmlpullvXmlPullParserException;
import orgxmlpullvXmlPullParserFactory; 

import comfasterxmljacksondatabindJsonNode;
import comgsonoauthOauth;
import comgsonoauthPay;
import comgsonutilHttpKit;
import comsyutilDatetimeUtil;
import comsyutilJsonUtil; 

@Controller
@RequestMapping("/pay")
public class WXPayController { 

  @RequestMapping(value = "wxprepaydo")
  public void jspay(HttpServletRequest request, HttpServletResponse response, String callback) throws Exception {
    // 获取openid
    String openId = SessionUtilgetAtt(request, "openId");
    if (openId == null) {
      openId = getUserOpenId(request);
    } 

    String appid = "wx16691fcb0523c1a4";
    String paternerKey = "ININGFENG1234567fdfwfdfd1ss234567"; 

    String out_trade_no = getTradeNo();
    Map<String, String> paraMap = new HashMap<String, String>();
    paraMapput("appid", appid);
    paraMapput("attach", "测试");
    paraMapput("body", "测试购买支付");
    paraMapput("mch_id", "10283271");
    paraMapput("nonce_str", create_nonce_str());
    paraMapput("openid", openId);
    paraMapput("out_trade_no", out_trade_no);
    paraMapput("spbill_create_ip", getAddrIp(request));
    paraMapput("total_fee", "1");
    paraMapput("trade_type", "JSAPI");
    paraMapput("notify_url", "http://wwwxxxco/bank/page/wxnotify");
    String sign = getSign(paraMap, paternerKey);
    paraMapput("sign", sign); 

    // 统一下单 https://apimchweixinqqcom/pay/unifiedorder
    String url = "https://apimchweixinqqcom/pay/unifiedorder"; 

    String xml = ArrayToXml(paraMap); 

    String xmlStr = HttpKitpost(url, xml); 

    // 预付商品id
    String prepay_id = ""; 

    if (xmlStrindexOf("SUCCESS") != -1) {
      Map<String, String> map = doXMLParse(xmlStr);
      prepay_id = (String) mapget("prepay_id");
    } 

    Map<String, String> payMap = new HashMap<String, String>();
    payMapput("appId", appid);
    payMapput("timeStamp", create_timestamp());
    payMapput("nonceStr", create_nonce_str());
    payMapput("signType", "MD5");
    payMapput("package", "prepay_id=" + prepay_id);
    String paySign = getSign(payMap, paternerKey); 

    payMapput("pg", prepay_id);
    payMapput("paySign", paySign); 

    WebUtilresponse(response, WebUtilpackJsonp(callback, JsonUtilwarpJsonNodeResponse(JsonUtilobjectToJsonNode(payMap))toString()));
  } 

  /**
   * map转成xml
   *
   * @param arr
   * @return
   */
  public String ArrayToXml(Map<String, String> arr) {
    String xml = "<xml>"; 

    Iterator<Entry<String, String>> iter = arrentrySet()iterator();
    while (iterhasNext()) {
      Entry<String, String> entry = iternext();
      String key = entrygetKey();
      String val = entrygetValue();
      xml += "<" + key + ">" + val + "</" + key + ">";
    } 

    xml += "</xml>";
    return xml;
  } 

  // 获取openId
  private String getUserOpenId(HttpServletRequest request) throws Exception {
    String code = requestgetParameter("code");
    if (code == null) {
      String openId = requestgetParameter("openId");
      return openId;
    }
    Oauth o = new Oauth();
    String token = ogetToken(code);
    JsonNode node = JsonUtilStringToJsonNode(token);
    String openId = nodeget("openid")asText();
    return openId;
  } 

  private String create_nonce_str() {
      String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
      String res = "";
      for (int i = 0; i < 16; i++) {
        Random rd = new Random();
        res += charscharAt(rdnextInt(charslength() - 1));
      }
      return res;
  } 

  private String getAddrIp(HttpServletRequest request){
    return requestgetRemoteAddr();
  } 

  private String create_timestamp() {
    return LongtoString(SystemcurrentTimeMillis() / 1000);
  } 

  private String getTradeNo(){
    String timestamp = DatetimeUtilformatDate(new Date(), DatetimeUtilDATETIME_PATTERN);
    return "HZNO" + timestamp;
  } 

  private String getSign(Map<String, String> params, String paternerKey )
      throws UnsupportedEncodingException {
    String string1 = PaycreateSign(params, false);
    String stringSignTemp = string1 + "&key=" + paternerKey;
    String signValue = DigestUtilsmd5Hex(stringSignTemp)toUpperCase();
    return signValue;
  } 

  private Map<String, String> doXMLParse(String xml)
      throws XmlPullParserException, IOException { 

    InputStream inputStream = new ByteArrayInputStream(xmlgetBytes()); 

    Map<String, String> map = null; 

    XmlPullParser pullParser = XmlPullParserFactorynewInstance()
        newPullParser(); 

    pullParsersetInput(inputStream, "UTF-8"); // 为xml设置要解析的xml数据 

    int eventType = pullParsergetEventType(); 

    while (eventType != XmlPullParserEND_DOCUMENT) {
      switch (eventType) {
      case XmlPullParserSTART_DOCUMENT:
        map = new HashMap<String, String>();
        break; 

      case XmlPullParserSTART_TAG:
        String key = pullParsergetName();
        if (keyequals("xml"))
          break; 

        String value = pullParsernextText();
        mapput(key, value); 

        break; 

      case XmlPullParserEND_TAG:
        break; 

      } 

      eventType = pullParsernext(); 

    } 

    return map;
  } 

}

四、H5支付

H5支付其实很简单,只需要调用微信内嵌浏览器的js方法就行(http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=7_7)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://wwwspringframeworkorg/tags" %>
<%
  String path = requestgetContextPath();
  String basePath = requestgetScheme() + "://" + requestgetServerName() + ":" + requestgetServerPort() + path + "/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 01 Transitional//EN" "http://wwwworg/TR/html4/loosedtd">
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=0, maximum-scale=0, user-scalable=0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="format-detection" content="telephone=no" />
<title>测试支付</title>
<link href="/css/csscss?v=0" rel="stylesheet" type="text/css">
</head> 

<body>
  <div class="index_box">
    <div class="apply_name">微信js支付测试</div> 

    <div class="branch_con">
      <ul>
        <li><span class="name">测试支付信息</span></li>
      </ul>
      <p class="cz_btn"><a href="javascript:pay();" class="btn_1">立即支付</a></p>
    </div>
  </div> 

  <script type="text/javascript" src="/js/zeptominjs"></script>
  <script type="text/javascript" src="/js/commonjs"></script>
  <script type="text/javascript"> 

  var appId = urlparameter("appId");
  var timeStamp = urlparameter("timeStamp");
  var nonceStr = urlparameter("nonceStr");
  var pg = urlparameter("pg");
  var signType = urlparameter("signType");
  var paySign = urlparameter("paySign"); 

   function onBridgeReady(){ 

      WeixinJSBridgeinvoke(
        'getBrandWCPayRequest', {
          "appId" : appId,   //公众号名称,由商户传入
          "timeStamp": timeStamp,     //时间戳,自1970年以来的秒数
          "nonceStr" : nonceStr, //随机串
          "package" : "prepay_id=" + pg,
          "signType" : signType,     //微信签名方式:
          "paySign" : paySign  //微信签名
        }, 

        function(res){
          if(reserr_msg == "get_brand_wcpay_request:ok" ) { 

            alert("支付成功");
          }   // 使用以上方式判断前端返回,微信团队郑重提示:reserr_msg将在用户支付成功后返回  ok,但并不保证它绝对可靠。
        }
      );
    } 

    function pay(){ 

      if (typeof WeixinJSBridge == "undefined"){
        if( documentaddEventListener ){
          documentaddEventListener('WeixinJSBridgeReady', onBridgeReady, false);
        }else if (documentattachEvent){
          documentattachEvent('WeixinJSBridgeReady', onBridgeReady);
          documentattachEvent('onWeixinJSBridgeReady', onBridgeReady);
        }
      }else{
        onBridgeReady();
      }  

    }
  </script>
</body>
</html> 

效果如下

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
, h5调用微信支付
, h5微信支付demo
微信h5支付
h5调用微信支付java、h5调用微信支付、h5调用支付宝支付接口、h5 页面调用微信支付、h5页面调用支付宝app,以便于您获取更多的相关知识。

时间: 2024-10-02 14:27:40

微信支付H5调用支付详解(java版)_java的相关文章

详解Java二叉排序树_java

一.二叉排序树定义1.二叉排序树的定义 二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree).其定义为:二叉排序树或者是空树,或者是满足如下性质的二叉树: ①若它的左子树非空,则左子树上所有结点的值均小于根结点的值: ②若它的右子树非空,则右子树上所有结点的值均大于根结点的值: ③左.右子树本身又各是一棵二叉排序树. 上述性质简称二叉排序树性质(BST性质),故二叉排序树实际上是满足BST性质的二叉树. 2.二叉排序树的性质 按中序遍历二叉

详解java定时任务_java

 在我们编程过程中如果需要执行一些简单的定时任务,无须做复杂的控制,我们可以考虑使用JDK中的Timer定时任务来实现.下面LZ就其原理.实例以及Timer缺陷三个方面来解析java Timer定时器. 一.简介      在java中一个完整定时任务需要由Timer.TimerTask两个类来配合完成. API中是这样定义他们的,Timer:一种工具,线程用其安排以后在后台线程中执行的任务.可安排任务执行一次,或者定期重复执行.由TimerTask:Timer 安排为一次执行或重复执行的任务.

详解Java中的指针、引用及对象的clone

对象|详解 Java语言的一个优点就是取消了指针的概念,但也导致了许多程序员在编程中常常忽略了对象与引用的区别,本文会试图澄清这一概念.并且由于Java不能通过简单的赋值来解决对象复制的问题,在开发过程中,也常常要要应用clone()方法来复制对象.本文会让你了解什么是影子clone与深度clone,认识它们的区别.优点及缺点.看到这个标题,是不是有点困惑:Java语言明确说明取消了指针,因为指针往往是在带来方便的同时也是导致代码不安全的根源,同时也会使程序的变得非常复杂难以理解,滥用指针写成的

微信小程序 require机制详解及实例代码_JavaScript

微信小程序 require机制详解 一, JS模块加载:一次性加载全部JS, 但并不一定立即执行. 先提一提微信小程序架构: 类浏览器 -> HTTP本地服务 -> 云端服务 微信小程序运行的架构,基本上是浏览器 -> HTTP本地服务 -> 云端服务, HTTP本地服务用来读取本地文件或者代理云端的文件资源.读取项目中JS文件, 是由HTTP本地服务取本地存储的脚本文件. 似乎比较简单,一个HTML 引用所有JS文件 既然采用了这种架构,那微信小程序就类似浏览器那样,借助一个HT

详解Java的堆内存与栈内存的存储机制_java

堆与内存优化    今天测了一个项目的数据自动整理功能,对数据库中几万条记录及图片进行整理操作,运行接近到最后,爆出了java.lang.outOfMemoryError,java heap space方面的错误,以前写程序很少遇到这种内存上的错误,因为java有垃圾回收器机制,就一直没太关注.今天上网找了点资料,在此基础上做了个整理.  一.堆和栈     堆-用new建立,垃圾回收器负责回收          1.程序开始运行时,JVM从OS获取一些内存,部分是堆内存.堆内存通常在存储地址的

C++聚合关系类的构造函数的调用顺序详解_C 语言

如图,表示一个聚合关系 下面就用简单的代码来实现 #pragma once class Engine { public: Engine(); ~Engine(); }; Engine.h #include <iostream> #include "Engine.h" using namespace std; Engine::Engine() { cout << "调用构造函数:Engine()" << endl; } Engine

专家为您详解JAVA数据库基本操作

数据|数据库|详解 java 数据库基本操作1.java数据库操作基本流程2.几个常用的重要技巧:     可滚动.更新的记录集     批量更新     事务处理 java数据库操作基本流程:取得数据库连接 - 执行sql语句 - 处理执行结果 - 释放数据库连接 1.取得数据库连接  1)用DriverManager取数据库连接   例子    String className,url,uid,pwd;    className = "oracle.jdbc.driver.OracleDri

详解Java中的正则表达式

详解Java中的正则表达式,并列出常用的正则表达式语法和一些常用的场景. 判断一个字符串是否是由数字组成: 当不使用正则表达式的时候的实现代码: public class RegexDemo01 { public static void main(String[] args) { String s = "23432324"; char c[] = s.toCharArray();//将字符串转换成字符数组 for (int i = 0; i < c.length; i++) {

asp.net 函数的定义 返回值 调用方法详解说明(vb.net/c#)

asp教程.net 函数的定义 返回值 调用方法详解说明(vb.net/c#),首页我们来看一个vb.net中开的asp.net教程创建一个函数的做法,如下 <script runat="server" language="VB">       Function getName() As String         Return "a"       End Function       Sub Page_Load(s As Obje