2018-03-14 15:20:34 blue_hh 阅读数 1061
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27838 人正在学习 去看看 秦子恒

微信小程序发送模板消息请求

最近公司接触到微信小程序的项目。自己也有幸参与其中,并且完成了发送模板消息的功能。所以自己总结一下,以便日后遇到类似情况可以少走一些弯路。也欢迎广大码农小伙伴一起交流一起进步。
俗话说磨刀不误砍柴工,特别是像这种使用微信接口的功能,必然要先了解其接口的主要作用。这是微信接口文档地址:https://mp.weixin.qq.com/debug/wxadoc/dev/api/notice.html#%E6%A8%A1%E7%89%88%E6%B6%88%E6%81%AF%E7%AE%A1%E7%90%86。通过这份文档,我们便可以知道我们需要的参数是什么。接下来就看进行实际的代码编写了。值得一提的是,在这些参数中,有一个data参数,是指模板的内容。这是一个变动的内容。即我们可以在这部分增加多个参数。为此我选择将这个data里面的参数重新做处理,并且用Map集合进行保存。所需要的类如下:
- 参数类(WXTemplate)
- data的类(WXTemplateData)
- 工具类(TemplateMsgUtil)(里面存放一些方法。比如获取请求微信接口需要的URL方法(getRequestUrl))即拼接好:https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN。ACCESS_TOKEN是自己获取得到的。由于一些工具类公司前辈已经写好,在这里我只需要调用即可。道友们可以百度一下相关数据的获取。


WXTemplate.java
public class WXTemplate {

    private String toUser;// 接受者(用户)的openid
    private String templateId;// 所需下发的模板消息的id
    private String page;// 点击模板卡片后的跳转页面
    private String formId;// 表单提交场景下,为 submit 事件带上的 formId;支付场景下,为本次支付的prepay_id
    private Map<String, WXTemplateData> data; // 模板内容,不填则下发空模板
    private String emphasisKeyword;// 模板需要放大的关键词,不填则默认无放大

    public WXTemplate(String toUser, String templateId, String page, String formId, Map<String, WXTemplateData> data,
            String emphasisKeyword) {
        super();
        this.toUser = toUser;
        this.templateId = templateId;
        this.page = page;
        this.formId = formId;
        this.data = data;
        this.emphasisKeyword = emphasisKeyword;
    }

    public WXTemplate() {
        super();
    }

    public String getToUser() {
        return toUser;
    }

    public void setToUser(String toUser) {
        this.toUser = toUser;
    }

    public String getTemplateId() {
        return templateId;
    }

    public void setTemplateId(String templateId) {
        this.templateId = templateId;
    }

    public String getPage() {
        return page;
    }

    public void setPage(String page) {
        this.page = page;
    }

    public String getFormId() {
        return formId;
    }

    public void setFormId(String formId) {
        this.formId = formId;
    }

    public Map<String, WXTemplateData> getData() {
        return data;
    }

    public void setData(Map<String, WXTemplateData> data) {
        this.data = data;
    }

    public String getEmphasisKeyword() {
        return emphasisKeyword;
    }

    public void setEmphasisKeyword(String emphasisKeyword) {
        this.emphasisKeyword = emphasisKeyword;
    }

}
WXTemplateData.java
    public class WXTemplateData {

    private String value; // 小标题

    private String color; // 模板内容字体的颜色,不填默认黑色

    public WXTemplateData(String value, String color) {
        super();
        this.value = value;
        this.color = color;
    }

    public WXTemplateData() {
        super();
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}
TemplateMsgUtil.java
    // 获取requestUrl
    public String getRequestUrl() {
        // 获取accessToken
        String accessToken = accessTokenUtil.getAccessToken(appId, secret);
        // requestUrl
        String requestUrl = SEND_API + "?access_token=" + accessToken;
        return requestUrl;
    }

接下来就是发送模板消息的方法(sendTemplateMsg)。

public boolean sendTemplateMsg(String openId, String templateId, String page, String formId,
            Map<String, WXTemplateData> data, String emphasisKeyword) {

        boolean result = false;
        WXTemplate template = new WXTemplate();
        template.setToUser(openId);
        template.setTemplateId(templateId);
        template.setPage(page);
        template.setFormId(formId);
        template.setData(data);
        template.setEmphasisKeyword(emphasisKeyword);

        String jsonMsg = JSONObject.toJSON(template).toString();

        TemplateMsgUtil templateMsgUtil = new TemplateMsgUtil();

        // 获取请求的url
        String requestUrl = templateMsgUtil.getRequestUrl();
        // 发送模板消息
        HttpResponse resp = HttpUtil.post(requestUrl, jsonMsg);
        if (resp.statusCode() == HttpStatus.OK.value()) {
            @SuppressWarnings("unchecked")
            Map<String, String> itemMap = JSONObject.parseObject(resp.body(), Map.class);
            // 判断是否发送成功
            if (itemMap.get("errcode").equals("0")) {
                result = true;
            } else {
                logger.info("发送模板消息失败:" + itemMap.get("errcode"));
                System.out.println("发送模板消息失败:" + itemMap.get("errcode"));
            }
        }
        return result;
    }

过程有点简单,因为公司前辈写好了很多东西,我直接调用即可。不过道理都差不多。欢迎大家一起交流探讨。

2016-12-08 17:14:37 qq_25821067 阅读数 8787
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27838 人正在学习 去看看 秦子恒

微信上接入平台的demo是PHP的,没得java的,所以我自己做接入的时候遇到了一点小问题。用java做带薪开发,首先就要先通过微信的接入配置,大概原理就是微信往服务器发送一些数据,然后在服务器端做一些数据的处理,再返回数据就行了。

微信官方的名称是:

验证服务器地址的有效性

下面是微信官方的文档:

开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带四个参数:

参数 描述
signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
timestamp 时间戳
nonce 随机数
echostr 随机字符串

开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。

加密/校验流程如下:
1. 将token、timestamp、nonce三个参数进行字典序排序
2. 将三个参数字符串拼接成一个字符串进行sha1加密
3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
实例开始

1:写个servlet类,来处理微信发送过来的数据:
package com.levi.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.levi.utils.SHA1;

/**
 * Servlet implementation class WeiXin
 */
public class WeiXin extends HttpServlet {
	private static final long serialVersionUID = 1L;
	 private static String Token = "leviweixin";  //这个是之前在微信上填写的Token数据,可以自定义
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WeiXin() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		 System.out.println("get请求,正确");
		System.out.println("获得微信请求!");
		String signature=request.getParameter("signature");
		String timestamp=request.getParameter("timestamp");
		String nonce=request.getParameter("nonce");
		String echostr=request.getParameter("echostr");
		System.out.println("signature="+signature);
		System.out.println("timestamp="+timestamp);
		System.out.println("nonce="+nonce);
		System.out.println("echostr="+echostr);
		System.out.println("Token="+Token);
		
		 List<String> params = new ArrayList<String>();  
         params.add(Token);  
         params.add(timestamp);  
         params.add(nonce);  
         //1. 将token、timestamp、nonce三个参数进行字典序排序  
         Collections.sort(params, new Comparator<String>() {  
             @Override  
             public int compare(String o1, String o2) {  
                 return o1.compareTo(o2);  
             }  
         }); 
         //2. 将三个参数字符串拼接成一个字符串进行sha1加密  
         String temp = SHA1.encode(params.get(0) + params.get(1) + params.get(2));  
         if (temp.equals(signature)) {  
        	 System.out.println("原:"+signature);
        	 System.out.println("测试:"+temp);
        	 System.out.println("匹配正确,传回微信了");
             response.getWriter().write(echostr);  
             System.out.println("传回微信成功");
         }  
		 else {  
        System.out.println("没有传回去数据,");
     } 
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	 System.out.println("post请求,错误了");
	}

}

2:需要一个SHA1 的util类:
/*
 * 微信公众平台(JAVA) SDK
 *
 * Copyright (c) 2016, Ansitech Network Technology Co.,Ltd All rights reserved.
 * http://www.ansitech.com/weixin/sdk/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.levi.utils;

import java.security.MessageDigest;

/**
 * <p>Title: SHA1算法</p>
 *
 * @author qsyang<yangqisheng274@163.com>
 */
public final class SHA1 {

    private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
                           '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    /**
     * Takes the raw bytes from the digest and formats them correct.
     *
     * @param bytes the raw bytes from the digest.
     * @return the formatted bytes.
     */
    private static String getFormattedText(byte[] bytes) {
        int len = bytes.length;
        StringBuilder buf = new StringBuilder(len * 2);
        // 把密文转换成十六进制的字符串形式
        for (int j = 0; j < len; j++) {
            buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
            buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
        }
        return buf.toString();
    }

    public static String encode(String str) {
        if (str == null) {
            return null;
        }
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
            messageDigest.update(str.getBytes());
            return getFormattedText(messageDigest.digest());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
3、配置下web.xml就行了
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>wx</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <description></description>
    <display-name>WeiXin</display-name>
    <servlet-name>WeiXin</servlet-name>
    <servlet-class>com.levi.service.WeiXin</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>WeiXin</servlet-name>
    <url-pattern>/WeiXin</url-pattern>
  </servlet-mapping>
</web-app>



点击提交,如果正确会显示配置成功。

注意事项:
1、一定要用到外网IP映射,可以用花生壳,或者用ngrok。端口要用80端口。用外网映射的目的就是模拟服务器,然后微信才能够给服务器发信息并且验证;
2、要多连续点击几次提交,直到ok为止,我测试的时候就发现,明明是对的,但是微信就说配置失败,后面我多次连续点击提交,非常快的速度连续点击提交。有个前提,要代码没写错哈,其实你把上面的3个代码块的文件复制进去应该是没得问题的。

2015-05-21 13:27:38 luciswe 阅读数 790
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27838 人正在学习 去看看 秦子恒

微信支付数据发送

微信支付数据需要以post的方式发送到微信支付接口

开发实现

创建package tools

创建文件夹tools

实现网络请求

创建http.go文件

package tools

import (
    "crypto/tls"
    "fmt"
    "io/ioutil"
    "net/http"
    "runtime"
    "strings"
)
//http get请求
func Get(geturl string) []byte {

    res, err := http.Get(geturl)
    if err != nil {
        fmt.Println(err)
    }

    robots, err := ioutil.ReadAll(res.Body)
    res.Body.Close()
    if err != nil {
        fmt.Println(err)

    }
    return robots
}

//http post请求
func Post(posturl string, data string) []byte {

    res, err := http.Post(posturl, "charset=UTF-8", strings.NewReader(data))
    if err != nil {
        fmt.Println(err)

    }
    robots, err := ioutil.ReadAll(res.Body)
    res.Body.Close()
    if err != nil {
        fmt.Println(err)

    }
    return robots

}
//http 带证书的post请求,证书格式为pem
func SSLPost(posturl string, data string) []byte {
    fmt.Println(runtime.GOROOT())
    cert, err := tls.LoadX509KeyPair(runtime.GOROOT()+"/cert.pem", runtime.GOROOT()+"/key.pem")
    if err != nil {
        fmt.Println(err)
    }
    config := tls.Config{Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true}
    tr := &http.Transport{
        TLSClientConfig: &config,
    }
    client := &http.Client{Transport: tr}

    res, err := client.Post(posturl, "application/x-www-form-urlencoded", strings.NewReader(data))
    if err != nil {
        fmt.Println(err)
    }
    robots, err := ioutil.ReadAll(res.Body)
    res.Body.Close()
    if err != nil {
        fmt.Println(err)

    }
    return robots

}

func Parserequest(r *http.Request) []byte {
    r.ParseForm()
    result, _ := ioutil.ReadAll(r.Body)
    return result
}
func Parseresponse(r *http.Response) []byte {
    result, _ := ioutil.ReadAll(r.Body)
    return result
}

不做详细解释,有不明白的可以留言

2015-11-30 20:50:38 a595364628 阅读数 4304
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27838 人正在学习 去看看 秦子恒

开发模式成为开发者时的消息校验原理

在开发者首次提交验证申请时,微信服务器将发送GET请求到填写的URL上,并且带上四个参数(signature、timestamp、nonce、echostr),开发者通过对签名(即signature)的效验,来判断此条消息的真实性。

此后,每次开发者接收用户消息的时候,微信也都会带上前面三个参数(signature、timestamp、nonce)访问开发者设置的URL,开发者依然通过对签名的效验判断此条消息的真实性。效验方式与首次提交验证申请一致。

参数 描述
signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
timestamp 时间戳
nonce 随机数
echostr 随机字符串

开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。

加密/校验流程如下:
1. 将token、timestamp、nonce三个参数进行字典序排序
2. 将三个参数字符串拼接成一个字符串进行sha1加密
3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

启用接口是由代码中的checkSignature()函数来实现校验的。如果对这一原理难以理解,可以暂时不用深究,继续看下面

 

成为开发者后消息收发时的原理

上一章节中图,当用户发送一个“?”时,系统回复了一个时间

这一原理的消息流程图如下所示。

从上图可以看出,用户在发送一个?后,微信服务器将组装一个消息发送给我们自己的服务器,自己的服务器然后回复一个时间,并且将该时间也按一定的规则组装,回复给公众账号,公众账号再回复给用户,在这个收发过程中,发送方和接收方进行了调换(ToUserName和FromUserName值互换),收发都是以xml格式在后台进行传输的,

所以掌握各种消息类型的接收回复就是进行微信公众平台开发的基础

下面对前面所述的各种消息类型讲解其XML数据包的格式。

2019-09-15 13:32:40 qq_35913969 阅读数 11
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27838 人正在学习 去看看 秦子恒

微信公众账号开发:
1.微信公共账号
2,公共账号的开发的条件
3,后台操作
、、、学习微信账号的开发需要知道什么是接口开发原理:
微信客户端->发送http请求,微信服务器端返回数据。
测试账号:可以获取服务号的所有权限。
微信公共平台后台操作介绍:
。。。。
微信服务器的数据交互流程:
微信客户端-》请求-》微信服务器-》请求-》第三方服务器-》返回微信服务器-》发送给用户。
ssh:主要是为远程登录回话和其他网络服务提供安全性的协议。
接口介绍:
json和xml:

<?php
$xml=<<<xml
<?xml version='1.0' encoding='utf-8'?>
<xml>
<msgid>1111</msgid>
</xml>
xml;
//simplexml_load_string()这个函数是把xml格式的数据转换成php的对象形式。
$obj = simplexml_load_string($xml);
//相当于调用里面的msgid;
$a = $obj -> msgid;
var_dum($a);
?>

、、通信流程:
打通服务器与微信之间的通信。
、、、接受微信发送的消息
、、、、、
微信回复单图文消息:
、、、、
回复多图文消息:
、、
curl可以使用url语法模拟游览器来传输数据

没有更多推荐了,返回首页