Browse Source

3/27

master
wangpengfei 1 year ago
parent
commit
3e30d5e9ec
  1. 2
      src/main/java/com/yxt/yythmall/api/ordorder/OrdOrderQuery.java
  2. 5
      src/main/java/com/yxt/yythmall/biz/ordorder/OrdOrderRest.java
  3. 25
      src/main/java/com/yxt/yythmall/biz/ordorder/OrdOrderService.java
  4. 5
      src/main/java/com/yxt/yythmall/biz/wx/RequestMes.java
  5. 77
      src/main/java/com/yxt/yythmall/biz/wx/WxConfig.java
  6. 28
      src/main/java/com/yxt/yythmall/biz/wx/invoice/ElectronicInvoice.java
  7. 47
      src/main/java/com/yxt/yythmall/biz/wx/invoice/ElectronicInvoiceService.java

2
src/main/java/com/yxt/yythmall/api/ordorder/OrdOrderQuery.java

@ -15,4 +15,6 @@ public class OrdOrderQuery implements Query {
private String state;
private String mainSid;
private String payTime;
private String totalTee;
private String outTradeNo;
}

5
src/main/java/com/yxt/yythmall/biz/ordorder/OrdOrderRest.java

@ -76,4 +76,9 @@ public class OrdOrderRest {
public ResultBean electronicInvoice(@RequestBody String mainSid) {
return ordOrderService.electronicInvoice(mainSid);
}
@PostMapping("/wxElectronicInvoice")
@ApiOperation(value = "微信电子发票")
public ResultBean wxElectronicInvoice(@RequestBody OrdOrderQuery query) {
return ordOrderService.wxElectronicInvoice(query);
}
}

25
src/main/java/com/yxt/yythmall/biz/ordorder/OrdOrderService.java

@ -15,13 +15,10 @@ import com.yxt.yythmall.api.appletgiftbag.GiftBagGoodss;
import com.yxt.yythmall.api.lpkcustomer.LpkCustomer;
import com.yxt.yythmall.api.lpkcustomer.LpkCustomerVo;
import com.yxt.yythmall.api.lpkgoods.LpkGoods;
import com.yxt.yythmall.api.lpkstore.LpkStore;
import com.yxt.yythmall.api.lpkstore.LpkStoreQuery;
import com.yxt.yythmall.api.lpkstore.LpkStoreVo;
import com.yxt.yythmall.api.ordorder.*;
import com.yxt.yythmall.api.ordorderdetails.OrdOrderDetail;
import com.yxt.yythmall.api.ordorderdetails.OrdOrderDetailVo;
import com.yxt.yythmall.api.shoppingcart.ShoppingCart;
import com.yxt.yythmall.api.shoppingcart.ShoppingCartQuery;
import com.yxt.yythmall.api.shoppingcart.ShoppingCartVo;
import com.yxt.yythmall.api.vegetablecellar.VegetableCellar;
@ -31,6 +28,8 @@ import com.yxt.yythmall.biz.lpkgoods.LpkGoodsService;
import com.yxt.yythmall.biz.ordorderdetails.OrdOrderDetailService;
import com.yxt.yythmall.biz.shoppingcart.ShoppingCartService;
import com.yxt.yythmall.biz.vegetablecellar.VegetableCellarService;
import com.yxt.yythmall.biz.wx.WxConfig;
import com.yxt.yythmall.biz.wx.RequestMes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
@ -647,6 +646,26 @@ public class OrdOrderService extends MybatisBaseService<OrdOrderMapper, OrdOrder
}
return rb.success();
}
public ResultBean wxElectronicInvoice(OrdOrderQuery query) {
ResultBean rb= ResultBean.fireFail();
// OrdOrder order=baseMapper.selectOne(new QueryWrapper<OrdOrder>().eq("sid",sid));
String url = WxConfig.AUTHORIZATION_PAGE.replace("ACCESS_TOKEN", WxConfig.wxAccessToken());
Map<String, String> map = new HashMap<>();
long timestamp = System.currentTimeMillis() / 1000;
map.put("s_pappid",WxConfig.getSPAppId());
map.put("order_id",query.getOutTradeNo());
map.put("money",query.getTotalTee());
map.put("timestamp",String.valueOf(timestamp));
map.put("source","wxa");
map.put("redirect_url","");
map.put("ticket",WxConfig.wxTicket());
map.put("type","1");
RequestMes res = new RestTemplate().postForObject(url,map,RequestMes.class);
if(!res.getErrcode().equals("0")){
return rb.setCode(res.getErrcode()).setMsg(res.getErrmsg());
}
return rb.success().setData(res);
}
/**
* 去除多余.0

5
src/main/java/com/yxt/yythmall/biz/wx/invoice/RequestMes.java → src/main/java/com/yxt/yythmall/biz/wx/RequestMes.java

@ -1,4 +1,4 @@
package com.yxt.yythmall.biz.wx.invoice;
package com.yxt.yythmall.biz.wx;
import lombok.Data;
@ -11,5 +11,6 @@ public class RequestMes {
private String errcode;
private String errmsg;
private String auth_url;
private String appid;
private String appid;
private String invoice_url;
}

77
src/main/java/com/yxt/yythmall/biz/wx/WxConfig.java

@ -6,12 +6,22 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
public class WxConfig {
private static final Logger L = LoggerFactory.getLogger(WxConfig.class);
private static final long token_expires_in = 5400 * 1000;
//获取token
private static final String WX_URL_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
//获取s_pappid
private static final String SETURL="https://api.weixin.qq.com/card/invoice/seturl?access_token=ACCESS_TOKEN";
//授权页
public static final String AUTHORIZATION_PAGE="https://api.weixin.qq.com/card/invoice/getauthurl?access_token=ACCESS_TOKEN";
//设置商户联系信息
public static final String merchant_contact="https://api.weixin.qq.com/card/invoice/setbizattr?action=set_contact&access_token=ACCESS_TOKEN";
//获取 ticket
private static final String ticket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card";
@ -26,8 +36,8 @@ public class WxConfig {
private static String mp_access_token;
private static long mp_token_create_timestamp;
public static final String WX_APPID = "wxc64c6cf0a06880e5";
private static final String WX_APPSECRET = "eb3a0794da05f12a94c92134030246f1";
public static final String WX_APPID = "wx1d44e0fcd110351a";
private static final String WX_APPSECRET = "e1ec3a9f542aa8bf2ffdf8248bdb69b1";
public static final String MP_APPID = "wx05604ce2a8bede05";
private static final String MP_APPSECRET = "3d36e8a61212cf773a2fa4e6c9a83334";
@ -79,7 +89,7 @@ public class WxConfig {
* @param secret
* @return
*/
public static String getTicket(String appid, String secret) {
public static String getTicket() {
String url = ticket.replace("ACCESS_TOKEN",wxAccessToken());
String res = new RestTemplate().getForObject(url, String.class);
JSONObject jsonObject = JSONObject.parseObject(res);
@ -94,9 +104,68 @@ public class WxConfig {
*/
public static String wxTicket() {
if (StringUtils.isBlank(wx_ticket) || System.currentTimeMillis() > (wx_ticket_create_timestamp + ticket_expires_in)) {
wx_ticket = getTicket(WX_APPID, WX_APPSECRET);
wx_ticket = getTicket();
wx_ticket_create_timestamp = System.currentTimeMillis();
}
return wx_ticket;
}
public static String getSPAppId(){
String url = SETURL.replace("ACCESS_TOKEN", WxConfig.wxAccessToken());
Map<String, String> map = new HashMap<>();
RequestMes res = new RestTemplate().postForObject(url,map,RequestMes.class);
String s_pappid=res.getInvoice_url().substring(res.getInvoice_url().indexOf("&")+10);
return s_pappid;
}
public static String merchantContact(){
String url = merchant_contact.replace("ACCESS_TOKEN", WxConfig.wxAccessToken());
Map<String,String> m=new HashMap<>();
m.put("phone","15932270269");
m.put("time_out","12345");
Map<String, Map<String,String>> map = new HashMap<>();
map.put("contact",m);
RequestMes res = new RestTemplate().postForObject(url,map,RequestMes.class);
return "1";
}
public static void main(String[] args) {
String url = merchant_contact.replace("ACCESS_TOKEN", WxConfig.wxAccessToken());
Map<String,String> m=new HashMap<>();
m.put("phone","15932270269");
m.put("time_out","12345");
Map<String, Map<String,String>> map = new HashMap<>();
map.put("contact",m);
RequestMes res = new RestTemplate().postForObject(url,map,RequestMes.class);
System.out.println(res);
}
/**
* @param $appId
* @param $uid
* @param $order_no
* @param $ticket_no
* @return bool|mixed
* @throws LocalServiceException
* @throws RemoteServiceException
*
* @desc 小程序开具电子发票的步骤如下
1 提前获取开票平台标识s_pappid因为同一个开票平台的s_pappid都相同所以获取s_pappid的操作只需要进行一次不同接入模式获取s_pappid的方法略有不同
如果商户接入模式为自建平台模式s_pappid通过调用调用获取自身开票平台识别码接口获得
2 商户获取获取access_token调用方法见获取access_token
3 设置商户联系方式调用方法见设置商户联系方式注意本步骤不能忽略否则将造成下一步获取授权页报错
4 商户获取授权页ticket调用方法见获取授权页ticket
5 商户获取授权页url上一步获取的授权页ticket将作为参数传入另外本环节里面作为参数传入的order_id要注意保留传递给开票平台作为向用户提供电子发票的依据调用方法见获取授权页链接
6 在小程序开票按钮的点击事件上部署跳转到小程序授权页的逻辑上一步获得的auth_url和开票小程序appid要作为参数传入调用方法见小程序打开授权页
7 商户在后台等待接收用户的授权完成事件获取授权事件方法见收取授权完成事件推送
8 创建发票卡券模板发票卡券模板应和背后的开票主体构成一一对应关系便于后续若开票主体发生变化时可以便捷修改调用方法见创建发票卡券模板
9 在自建发票平台开具电子发票
10 上传发票PDF文件此步骤获得的s_media_id起到关联PDF和发票卡券的作用将作为参数在下一步的插卡接口中传入调用方法见上传PDF
11 将电子发票添加到用户微信卡包调用方法见将电子发票卡券插入用户卡包
*/
}

28
src/main/java/com/yxt/yythmall/biz/wx/invoice/ElectronicInvoice.java

@ -1,28 +0,0 @@
package com.yxt.yythmall.biz.wx.invoice;
import com.alibaba.fastjson.JSONObject;
import com.yxt.common.core.result.ResultBean;
import com.yxt.yythmall.biz.wx.WxConfig;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
/**
* @author wangpengfei
* @date 2024/3/15 16:09
*/
public class ElectronicInvoice {
private static final String AUTHORIZATION_PAGE="https://api.weixin.qq.com/card/invoice/getauthurl?access_token=ACCESS_TOKEN";
public ResultBean getAuthorizationPage(String appid, String secret) {
ResultBean rb= ResultBean.fireFail();
String url = AUTHORIZATION_PAGE.replace("ACCESS_TOKEN", WxConfig.wxAccessToken());
Map<String, String> map = new HashMap<>();
RequestMes res = new RestTemplate().postForObject(url,map,RequestMes.class);
if(!res.getErrcode().equals("0")){
return rb;
}
return rb;
}
}

47
src/main/java/com/yxt/yythmall/biz/wx/invoice/ElectronicInvoiceService.java

@ -0,0 +1,47 @@
package com.yxt.yythmall.biz.wx.invoice;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yxt.common.core.result.ResultBean;
import com.yxt.yythmall.api.ordorder.OrdOrder;
import com.yxt.yythmall.biz.ordorder.OrdOrderService;
import com.yxt.yythmall.biz.wx.RequestMes;
import com.yxt.yythmall.biz.wx.WxConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
/**
* @author wangpengfei
* @date 2024/3/15 16:09
*/
@Service
public class ElectronicInvoiceService {
@Autowired
OrdOrderService ordOrderService;
private static final String AUTHORIZATION_PAGE="https://api.weixin.qq.com/card/invoice/getauthurl?access_token=ACCESS_TOKEN";
public ResultBean getAuthorizationPage(String sid) {
ResultBean rb= ResultBean.fireFail();
OrdOrder order=ordOrderService.getOne(new QueryWrapper<OrdOrder>().eq("sid",sid));
String url = AUTHORIZATION_PAGE.replace("ACCESS_TOKEN", WxConfig.wxAccessToken());
Map<String, String> map = new HashMap<>();
long timestamp = System.currentTimeMillis() / 1000;
map.put("s_pappid",WxConfig.getSPAppId());
map.put("order_id",order.getOutTradeNo());
map.put("money",order.getTotalTee());
map.put("timestamp",String.valueOf(timestamp));
map.put("source","wxa");
map.put("redirect_url","");
map.put("ticket",WxConfig.wxTicket());
map.put("type","1");
RequestMes res = new RestTemplate().postForObject(url,map,RequestMes.class);
if(!res.getErrcode().equals("0")){
return rb.setCode(res.getErrcode()).setMsg(res.getErrmsg());
}
return rb.success().setData(res);
}
}
Loading…
Cancel
Save