诺诺开票

环境:.NetCore、NuonuoSDK

  1 /// <summary>
  2 /// 申请诺诺电子发票
  3 /// </summary>
  4 /// <param name="applySource">1:支付完自动开票;2:手动选择小订单开票</param>
  5 /// <returns></returns>
  6 public async Task ApplyEInvoice(string orderNo, Guid invoiceTitleId, int applySource)
  7 {
  8     try
  9     {
 10         var orderDetailList = await _orderDetailRepository.GetListAsync(f => f.OrderNo == orderNo);
 11         if (applySource == 2)
 12         {
 13             orderDetailList = await _orderDetailRepository.GetListAsync(f => f.OrderDetailNo == orderNo);
 14         }
 15         if (orderDetailList != null)
 16         {
 17             var invoiceTitle = await _invoiceTitleRepository.GetAsync(invoiceTitleId);
 18             if (invoiceTitle != null)
 19             {
 20                 foreach (var orderDetail in orderDetailList)
 21                 {
 22                     var fpkjModel = _fpkjRequestOptions.Value;
 23                     fpkjModel.buyerName = invoiceTitle.Name;
 24                     fpkjModel.buyerTaxNum = invoiceTitle.TaxNumber;
 25                     fpkjModel.buyerTel = invoiceTitle.Mobile;
 26                     fpkjModel.buyerAddress = invoiceTitle.Address;
 27                     fpkjModel.buyerAccount = invoiceTitle.Bank + invoiceTitle.BankNumber;
 28                     fpkjModel.orderNo = orderDetail.OrderDetailNo;
 29                     fpkjModel.invoiceDate = orderDetail.CreationTime.ToString("yyyy-MM-dd HH:mm:ss");
 30                     fpkjModel.buyerPhone = invoiceTitle.SendPhoneNumber;  //购方手机(pushMode为1或2时,此项必填
 31                     fpkjModel.email = invoiceTitle.SendEmailAddress;  //推送邮箱 推送邮箱(pushMode为0或2时,此项为必填,同时受企业资质是否必填控制)
 32                     fpkjModel.pushMode = "2";    //推送方式:-1;不推送;0;邮箱;1;手机(默认); 2;邮箱、手机
 33                     fpkjModel.invoiceType = "1";    //蓝票
 34                     fpkjModel.invoiceLine = "pc";   //电子发票(普通发票)-即数电普票(电子)
 35                     fpkjModel.invoiceDetail = new List<InvoiceDetail>()
 36                     {
 37                         new InvoiceDetail()
 38                         {
 39                             taxIncludedAmount = orderDetail.OrderAmount.ToString(),
 40                             withTaxFlag = "1",
 41                             num = "1"
 42                         },
 43                     };
 44 
 45                     //string str = await _openInvoiceManager.GetEInvoiceTokenAsync();
 46                     //var pxResponseResult = JsonConvert.DeserializeObject<PxResponseResult<JYEInvoiceTokenResponse>>(str);
 47                     //var tokenInfo = pxResponseResult.Data;
 48 
 49                     (string invoiceSerialNum, string message) openInvoiceResponse = _openInvoiceManager.OpenInvoice(fpkjModel, fpkjModel.salerTaxNum);
 50                     Logger.LogInformation("申请诺诺电子发票:流水号:" + openInvoiceResponse.invoiceSerialNum + ",描述:" + openInvoiceResponse.message);
 51                     if (!string.IsNullOrEmpty(openInvoiceResponse.invoiceSerialNum) || openInvoiceResponse.message == "订单编号或流水号不能重复")
 52                     {
 53                         var openInvoice = await _openInvoiceRepository.FirstOrDefaultAsync(f => f.OrderNo == orderDetail.OrderDetailNo);
 54                         if (openInvoice == null)
 55                         {
 56                             OpenInvoiceRecord openInvoiceRecord = new OpenInvoiceRecord()
 57                             {
 58                                 InvoiceNature = invoiceTitle.InvoiceNature,
 59                                 InvoiceStatus = (EnumInvoiceStatus)20,
 60                                 OrderNo = orderDetail.OrderDetailNo,
 61                                 PayAmount = orderDetail.OrderAmount,
 62                                 PurchaserInvoiceTitle = invoiceTitle.Name,
 63                                 PurchaserIdTaxpayer = invoiceTitle.TaxNumber,
 64                                 PurchaserAddressMobile = invoiceTitle.Mobile,
 65                                 PurchaserBank = invoiceTitle.Bank,
 66                                 PurchaserBankNumber = invoiceTitle.BankNumber,
 67                                 UserEmail = invoiceTitle.SendEmailAddress,
 68                                 UserMobile = invoiceTitle.SendPhoneNumber,
 69                                 SerialNo = openInvoiceResponse.invoiceSerialNum
 70                             };
 71                             openInvoice = await _openInvoiceRepository.InsertAsync(openInvoiceRecord, true);
 72                         }
 73 
 74                         //查询发票:提交成功后,返回是开票提交成功,会立即返回开票流水号,这里电子票的状态不是最终状态,如果使用流水号查询开票信息,有可能是开票中状态
 75                         var query = QueryInvoiceAsync(openInvoice, fpkjModel.salerTaxNum);
 76                     }
 77                 }
 78             }
 79             else
 80             {
 81                 Logger.LogInformation("申请诺诺电子发票:未查询到发票抬头信息");
 82             }
 83         }
 84         else
 85         {
 86             Logger.LogInformation("申请诺诺电子发票:未查询到订单信息");
 87         }
 88     }
 89     catch (Exception ex)
 90     {
 91         Logger.LogInformation("申请诺诺电子发票:" + ex.Message);
 92     }
 93 }
 94 
 95 /// <summary>
 96 /// 查询发票,完善发票信息
 97 /// </summary>
 98 private async Task QueryInvoiceAsync(OpenInvoiceRecord invoice, string taxNum)
 99 {
100     // 等待 5 秒钟
101     await Task.Delay(TimeSpan.FromSeconds(10));
102     Logger.LogInformation($"查询发票信息:{JsonConvert.SerializeObject(invoice)}");
103     string fpckMsg = "查询发票信息";
104     while (!string.IsNullOrEmpty(fpckMsg))
105     {
106         List<string> serialNos = new List<string>();
107         if (!string.IsNullOrEmpty(invoice.SerialNo))
108         {
109             serialNos.Add(invoice.SerialNo);
110         }
111         List<string> orderNos = new List<string>()
112         {
113             invoice.OrderNo
114         };
115 
116         (List<InvoicePdf> pdfList, string msg) fpInfoList = _openInvoiceManager.QueryInvoice(
117             new FpcxRequest()
118             {
119                 serialNos = serialNos,
120                 orderNos = orderNos
121             },
122             taxNum);
123         fpckMsg = fpInfoList.msg;
124 
125         if (fpInfoList.pdfList != null && string.IsNullOrEmpty(fpckMsg))
126         {
127             Logger.LogInformation($"查询发票信息:pdfList:{JsonConvert.SerializeObject(fpInfoList.pdfList)}");
128             InvoicePdf invoicePdf = fpInfoList.pdfList.FirstOrDefault<InvoicePdf>();
129             if (!string.IsNullOrEmpty(invoicePdf.URL))
130             {
131                 invoice.InvoiceUrl = invoicePdf.URL;
132                 invoice.InvoiceCode = invoicePdf.FPDM;
133                 invoice.InvoiceNo = invoicePdf.FPHM;
134                 invoice.SerialNo = invoicePdf.FPLSH;
135                 invoice.CheckCode = invoicePdf.JYM;
136                 invoice.InvoiceStatus = (EnumInvoiceStatus)2;
137                 invoice.InvoiceTime = DateTimeHelper.StampToDateTime(invoicePdf.KPRQ.ToString());
138 
139                 var temp = await _openInvoiceRepository.UpdateAsync(invoice);
140                 if (temp != null)
141                 {
142                     return;
143                 }
144             }
145         }
146         else
147         {
148             Logger.LogInformation($"查询发票信息:描述:{fpInfoList.msg},{JsonConvert.SerializeObject(fpInfoList.pdfList)}");
149         }
150     }
151 }
View Code
 1 /// <summary>
 2 /// 诺诺开放平台开票
 3 /// </summary>
 4 /// <returns></returns>
 5 public (string invoiceSerialNum, string message) OpenInvoice(FpkjRequest fpkj, string taxNum)
 6 {
 7     foreach (var item in fpkj.invoiceDetail)
 8     {
 9         var sl = Convert.ToDouble(item.taxRate);
10         var hsje = Convert.ToDouble(item.taxIncludedAmount);
11         var xmdj = 0.00;//项目单价
12         var se = 0.00;//税额
13         var bhsje = 0.00;//不含税金额
14         if (item.withTaxFlag == "1")
15         {
16             xmdj = hsje / Convert.ToInt32(item.num);//项目单价
17             se = Math.Round(hsje * sl / (1 + sl), 2);
18             bhsje = hsje - se;
19         }
20         else
21         {
22             xmdj = hsje / Convert.ToInt32(item.num) / (1 + sl);
23             se = Math.Round(xmdj * Convert.ToInt32(item.num) * sl, 2);
24             bhsje = hsje - se;
25         }
26         item.tax = se.ToString();
27         item.taxExcludedAmount = bhsje.ToString();
28         item.price = xmdj.ToString();
29     }
30 
31     string jsonStr = JsonConvert.SerializeObject(fpkj);
32     string content = "{";
33     content += "\"order\":";
34     content += jsonStr;
35     content += "    }";
36     Logger.LogInformation($"诺诺开放平台开票接口请求:{content}");
37     var invoiceConfigDto = _invoiceConfigOptions.Value;
38     var returnStr = NuoNuoSdkHelper.sendRequest("nuonuo.OpeMplatform.requestBillingNew", content, taxNum, invoiceConfigDto);
39     Logger.LogInformation($"诺诺开放平台开票接口返回:{returnStr}");
40     var FpkjReturnModel = JsonConvert.DeserializeObject<FpkjResponse>(returnStr);
41     var invoiceSerialNum = "";
42     if (FpkjReturnModel.code == "E0000")
43     {
44         var resultSerialNumModel = JsonConvert.DeserializeObject<resultSerialNum>(JsonConvert.SerializeObject(FpkjReturnModel.result));
45         invoiceSerialNum = resultSerialNumModel.invoiceSerialNum;
46     }
47 
48     return (invoiceSerialNum, FpkjReturnModel.describe);
49 }
50 
51 /// <summary>
52 /// 诺诺开放平台发票查询
53 /// </summary>
54 /// <returns></returns>
55 public (List<InvoicePdf> pdfList, string msg) QueryInvoice(FpcxRequest fpcx, string taxNum)
56 {
57     string content = JsonConvert.SerializeObject(fpcx);
58     Logger.LogInformation($"诺诺开放平台发票查询接口请求:{content}");
59     var invoiceConfigDto = _invoiceConfigOptions.Value;
60     var returnStr = NuoNuoSdkHelper.sendRequest("nuonuo.OpeMplatform.queryInvoiceResult", content, taxNum, invoiceConfigDto);
61     Logger.LogInformation($"诺诺开放平台发票查询接口返回:{returnStr},参数:{content}---{taxNum}---{JsonConvert.SerializeObject(invoiceConfigDto)}");
62 
63     string msg = "";
64     List<InvoicePdf> dataList = new List<InvoicePdf>();
65     var FpcxReturnModel = JsonConvert.DeserializeObject<FpcxResponse>(returnStr);
66     if (FpcxReturnModel.code == "E0000")
67     {
68         var fpInfo = FpcxReturnModel.result;
69         if (fpInfo.Count < 1)
70         {
71             msg = "发票查询:未查询到发票数据";
72         }
73         else
74         {
75             foreach (var item in fpInfo)
76             {
77                 var pdfInfo = new InvoicePdf();
78                 pdfInfo.DDLSH = item.orderNo;
79                 pdfInfo.FPLSH = item.serialNo;
80                 pdfInfo.FPDM = item.invoiceCode;
81                 pdfInfo.FPHM = item.invoiceNo;
82                 pdfInfo.KPRQ = item.invoiceTime;
83                 pdfInfo.URL = item.pdfUrl;
84                 pdfInfo.JYM = item.checkCode;
85                 pdfInfo.status = item.status;
86                 pdfInfo.statusMsg = item.statusMsg;
87                 pdfInfo.failCause = item.failCause;
88                 dataList.Add(pdfInfo);
89             }
90         }
91     }
92     else
93     {
94         msg = FpcxReturnModel.describe;
95     }
96 
97     return (dataList, msg);
98 }
View Code
 1 public class NuoNuoSdkHelper
 2 {
 3     /// <summary>
 4     /// 调用诺诺开放平台API
 5     /// </summary>
 6     /// <returns></returns>
 7     public static string sendRequest(string method, string content, string taxNum, InvoiceConfigDto _invoiceConfigDto)
 8     {
 9         string senid = Guid.NewGuid().ToString().Replace("-", "").Substring(0, 32); // 唯一标识,由企业自己生成32位随机码
10         return NNOpenSDK.sendPostSyncRequest(_invoiceConfigDto.Url, senid, _invoiceConfigDto.AppKey, _invoiceConfigDto.AppSecret, _invoiceConfigDto.Token, taxNum, method, content);
11     }
12 }
View Code
 1 public override void ConfigureServices(ServiceConfigurationContext context)
 2 {
 3     var configuration = context.Services.GetConfiguration();
 4 
 5     ConfigureSalerInvoiceConfig(context, configuration);
 6     ConfigureInvoiceConfig(context, configuration);
 7 }
 8 
 9  /// <summary>
10  /// 设置发票配置信息
11  /// </summary>
12  /// <param name="context"></param>
13  /// <param name="configuration"></param>
14  private void ConfigureInvoiceConfig(ServiceConfigurationContext context, IConfiguration configuration)
15  {
16      context.Services.Configure<InvoiceConfigDto>(options =>
17      {
18          options.AppKey = configuration["InvoiceConfigString:AppKey"];
19          options.AppSecret = configuration["InvoiceConfigString:AppSecret"];
20          options.Url = configuration["InvoiceConfigString:Url"];
21          options.Token = configuration["InvoiceConfigString:ZheJiangJianYuanShuDianToken"];
22      });
23  }
24 
25  /// <summary>
26  /// 设置销售方发票配置信息
27  /// </summary>
28  /// <param name="context"></param>
29  /// <param name="configuration"></param>
30  private void ConfigureSalerInvoiceConfig(ServiceConfigurationContext context, IConfiguration configuration)
31  {
32      context.Services.Configure<FpkjRequest>(options =>
33      {
34          options.clerk = configuration["SalerInvoiceConfig:clerk"];
35          options.checker = configuration["SalerInvoiceConfig:checker"];
36          options.payee = configuration["SalerInvoiceConfig:payee"];
37          options.salerTaxNum = configuration["SalerInvoiceConfig:salerTaxNum"];
38          options.salerTel = configuration["SalerInvoiceConfig:salerTel"];
39          options.salerAddress = configuration["SalerInvoiceConfig:salerAddress"];
40          options.salerAccount = configuration["SalerInvoiceConfig:salerAccount"];
41      });
42  }
View Code

 

//销售方发票配置
"SalerInvoiceConfig": {
  "clerk": "", //开票人
  "checker": "", //复核人
  "payee": "", //收款人
  "salerTaxNum": "", //销售方税号(测试)
  "salerTel": "", //销售方电话 
  "salerAddress": "", //销售方地址 
  "salerAccount": "" //销方银行账号和开户行地址
},
//发票配置
"InvoiceConfigString": {
  "AppKey": "",
  "AppSecret": "",
  "Url": "https://sandbox.nuonuocs.cn/open/v1/services",
  "ZheJiangJianYuanShuDianToken": "", //获取开票token密钥
  "InvoiceAmountLimit": 10000 //发票最大金额限制
}
posted @ 2024-02-19 11:36  智者见智  阅读(192)  评论(0编辑  收藏  举报