zoukankan      html  css  js  c++  java
  • 连接QuickBooks Online实现于IOS App数据同步功能的个人记录

    公司项目需要用WebService与QBO实现后台数据同步,由于国内没有做过类似第三方产品接口的资料,前前后后找了N久,终于实现功能,现把实现功能步骤贴上来分享:

    QBO开发者地址(主要用于创建QBO的APP和获取KEY和Token)

    https://developer.intuit.com/

    QBO后台数据管理地址(存放常见的Invoice,Customer等数据)

    https://qbo.intuit.com/qbo28/login?webredir

    QBO官方参考文档地址

    https://developer.intuit.com/docs/0100_accounting/0000_release_notes

    1. 获取token的key和secret,在QBO开发者地址的My APPs中点击右上角Create New APP来创建一个新的App,选择Select APIs,然后勾选Accounting和Payments,创建后进入控制台界面,有三个Deveolpment、Production、AppCards三个选项卡。

    Development:用与开发者模式下测试,在Development下只能连接到SandBox。SandBox可以在顶栏 右边栏下拉菜单找到。

    Production:用于连接 QBO后台数据管理 地址中的数据

    APPCards:用来发布你创建的APP的后台管理卡片

    2.Token的Key和Secret在Development/Production的Keys栏下,分别是OAuth Consumer Key和OAuth Consumer Secret

    3.获取二次Token的Key和Secret,

    参照以下地址中的步骤:

    https://developer.intuit.com/docs/0050_quickbooks_api/0020_authentication_and_authorization/connect_from_within_your_app

    在Connect from within your app栏可以找到具体操作步骤

    需要以下三个地址:Intuit OAuth Service URLs

    得到返回的三个参数:分别是

    • realmId
    • oauth_verifier
    • oauth_token

    在认证时候,如果是用Development的Key和Secret,是会默认连接到Sandbox的数据的,所以想看到公共的 QBO后台数据管理 中的数据,需要用Production中的Key和Secret。

    获得二次Token的Key和Secret后,就可以通过SDK或REST API的方式连接到QBO来获取和推送数据了。

    一、SDK方式同步QBO:

    官方SDK文档:

    http://developer.qbapi.com/Quickbooks-Online-API-QuickStart.aspx

    官方SDK下载:

    https://www.nuget.org/packages/IppDotNetSdkForQuickBooksApiV3/

    如果需要.NET连接QBO的后台示例代码,也可以在以下URL中找到

    http://developer.qbapi.com/Connect-to-Quickbooks-Online.aspx#

    1.添加引用:

    using DevDefined.OAuth.Consumer;
    using DevDefined.OAuth.Framework;
    using Intuit.Ipp.Core;
    using Intuit.Ipp.DataService;
    using Intuit.Ipp.Security;

    2.定义GetServiceContext方法,用于返回ServiceContext

    public static ServiceContext GetServiceContext(string AccessToken, string AccessTokenSecret, string CompanyId)
    {

    OAuthRequestValidator oauthValidator = new OAuthRequestValidator(AccessToken, AccessTokenSecret, consumerKey, consumerSecret);
    ServiceContext context = new ServiceContext(CompanyId, IntuitServicesType.QBO, oauthValidator);
    context.IppConfiguration.BaseUrl.Qbo = "https://quickbooks.api.intuit.com/";
    return context;
    }

    consumerKey和consumerSecret是QBO开发者地址中Production下的OAuth Consumer Key和OAuth Consumer Secret

    GetServiceContext方法中的参数,AccessToken、AccessTokenSecret和CompanyId分别是二次Token中返回的oauth_token、oauth_verifier和realmId

    3.创建QBO连接:

    public static DataService ConnectToQBO(string AccessToken, string AccessTokenSecret, string CompanyId)
    {
    OAuthRequestValidator oauthValidator = new OAuthRequestValidator(AccessToken, AccessTokenSecret, consumerKey, consumerSecret);
    ServiceContext context = GetServiceContext(AccessToken, AccessTokenSecret, CompanyId);
    DataService dataService = new DataService(context);
    return dataService;
    }

    4.查询QBO对应的信息:

    返回Invoice信息:

    DataService dataService = QBOCommonUtility.ConnectToQBO(AccessToken, AccessTokenSecret, CompanyId);
    List<Invoice> invoiceList = dataService.FindAll(new Invoice(), 1, 100).ToList();

    5.根据条件查询QBO信息:

    1)方法一:

    DataService dataService = QBOCommonUtility.ConnectToQBO(AccessToken, AccessTokenSecret, CompanyId);
    Invoice invoice = dataService.FindAll(new Invoice()).Where(a => a.Id == request.Invoice.QBOId).SingleOrDefault();

    2)方法二:

    ServiceContext context = QBOCommonUtility.GetServiceContext(AccessToken, AccessTokenSecret, CompanyId);
    QueryService<Invoice> queryService = new QueryService<Invoice>(context);
    string query = string.Format("SELECT * FROM Invoice where Id='{0}'",id);
    IEnumerable<Invoice> invoices = queryService.ExecuteIdsQuery(query);

    6.插入一个新的Customer到QBO

    public static Customer InsertQBOCustomer(QBOCustomerRequest request)
    {
    string AccessToken = request.AccessToken;
    string AccessTokenSecret= request.AccessSecret;
    string CompanyId = request.CompanyId;
    DataService dataService = QBOCommonUtility.ConnectToQBO(AccessToken, AccessTokenSecret, CompanyId);
    Customer customer = new Customer();
    //Mandatory Fields

    customer.Title = request.Customer.Title == null ? "" : request.Customer.Title;
    customer.GivenName = request.Customer.GivenName == null ? "" : request.Customer.GivenName;
    customer.MiddleName = request.Customer.MiddleName == null ? "" : request.Customer.MiddleName;
    customer.FamilyName = request.Customer.FamilyName == null ? "" : request.Customer.FamilyName;
    customer.Notes = request.Customer.Notes == null ? "" : request.Customer.Notes;
    customer.Suffix = request.Customer.Suffix == null ? "" : request.Customer.Suffix;
    customer.FullyQualifiedName = request.Customer.FullyQualifiedName == null ? "" : request.Customer.FullyQualifiedName;
    customer.CompanyName = request.Customer.CompanyName == null ? "" : request.Customer.CompanyName;
    customer.DisplayName = request.Customer.DisplayName == null ? "" : request.Customer.DisplayName;

    if (request.Customer.BillAddr!=null)
    {
    customer.BillAddr = new PhysicalAddress();
    customer.BillAddr.City = request.Customer.BillAddr.City == null ? "" : request.Customer.BillAddr.City;
    customer.BillAddr.Country = request.Customer.BillAddr.Country == null ? "" : request.Customer.BillAddr.Country;
    customer.BillAddr.CountrySubDivisionCode = request.Customer.BillAddr.CountrySubDivisionCode == null ? "" : request.Customer.BillAddr.CountrySubDivisionCode;
    customer.BillAddr.Line1 = request.Customer.BillAddr.Line1 == null ? "" : request.Customer.BillAddr.Line1;
    customer.BillAddr.PostalCode = request.Customer.BillAddr.PostalCode == null ? "" : request.Customer.BillAddr.PostalCode;
    }

    if(request.Customer.PrimaryPhone!=null)
    {
    customer.PrimaryPhone = new TelephoneNumber();
    customer.PrimaryPhone.FreeFormNumber = request.Customer.PrimaryPhone.FreeFormNumber == null ? "" : request.Customer.PrimaryPhone.FreeFormNumber;
    }

    if(request.Customer.PrimaryEmailAddr!=null)
    {
    customer.PrimaryEmailAddr = new EmailAddress();
    customer.PrimaryEmailAddr.Address = request.Customer.PrimaryEmailAddr.Address == null ? "" : request.Customer.PrimaryEmailAddr.Address;
    }


    Customer resultCustomer = dataService.Add(customer) as Customer;
    return resultCustomer;
    }

    8.插入新的Invoice到QBO

    internal static Invoice CreateInvoice(QBOInvoiceRequest request, Customer customer)
    {
    try
    {
    string AccessToken = request.AccessToken;
    string AccessTokenSecret = request.AccessTokenSecret;
    string CompanyId = request.Invoice.QBOCompanyId;
    DataService dataService = QBOCommonUtility.ConnectToQBO(AccessToken, AccessTokenSecret, CompanyId);

    Item item = dataService.FindAll(new Item(), 1, 1).SingleOrDefault();

    Invoice invoice = new Invoice();
    //Mandatory fields
    invoice.DocNumber = Guid.NewGuid().ToString("N").Substring(0, 10);
    invoice.TxnDate = Convert.ToDateTime(request.Invoice.InvoiceDate);//DateTime.Today.Date;//
    invoice.TxnDateSpecified = true;
    invoice.CustomerRef = new ReferenceType()
    {
    name = customer.GivenName,
    Value = customer.Id
    };

    Line line = new Line();

    line.Amount = request.Invoice.Amount;//request.Invoice.Amount;//10000;
    line.DetailType = LineDetailTypeEnum.DescriptionOnly;
    line.AmountSpecified = true;
    line.Description = "Desc Invoice";
    line.DetailType = LineDetailTypeEnum.SalesItemLineDetail;
    line.DetailTypeSpecified = true;

    SalesItemLineDetail lineSalesItemLineDetail = new SalesItemLineDetail();
    //Line Sales Item Line Detail - ItemRef
    lineSalesItemLineDetail.ItemRef = new ReferenceType()
    {
    name = item.Name,
    Value = item.Id
    };
    //Line Sales Item Line Detail - UnitPrice
    lineSalesItemLineDetail.AnyIntuitObject = 0m;
    lineSalesItemLineDetail.ItemElementName = ItemChoiceType.UnitPrice;

    //Line Sales Item Line Detail - Qty
    lineSalesItemLineDetail.Qty = 0;
    lineSalesItemLineDetail.QtySpecified = true;

    //Line Sales Item Line Detail - TaxCodeRef
    //For US companies, this can be 'TAX' or 'NON'
    lineSalesItemLineDetail.TaxCodeRef = new ReferenceType()
    {
    Value = "NON"
    };

    //Line Sales Item Line Detail - ServiceDate
    lineSalesItemLineDetail.ServiceDate = DateTime.Now.Date;
    lineSalesItemLineDetail.ServiceDateSpecified = true;

    //Assign Sales Item Line Detail to Line Item
    line.AnyIntuitObject = lineSalesItemLineDetail;
    //Assign Line Item to Invoice
    invoice.Line = new Line[] { line };

    Invoice addInvoice = dataService.Add(invoice) as Invoice;
    return addInvoice;


    //Invoice invoice1 = invoiceList[0];
    //invoice1.CustomerRef = invoice.CustomerRef;
    //Invoice addInvoice1 = dataService.Update(invoice1);

    //Batch batch = dataService.CreateNewBatch();
    //batch.Add(invoice, "bId1", OperationEnum.create);
    //batch.Execute();
    }
    catch (ValidationException exception)
    {
    Console.WriteLine("Message:{0}, ErrorCode:{1}", exception.Message, exception.ErrorCode);
    foreach (IdsError idsError in exception.InnerExceptions)
    {
    Console.WriteLine("ErrorCode:{0}, Message:{1}, Element:{2}, Detail:{3}", idsError.ErrorCode, idsError.Message,
    idsError.Element, idsError.Detail);
    }
    return null;
    }

    }

    9.更新Customer到QBO

    public static Customer UpdateQBOCustomer(QBOCustomerRequest request, string id)
    {
    string AccessToken = request.AccessToken;
    string AccessTokenSecret = request.AccessSecret;
    string CompanyId = request.CompanyId;

    DataService dataService = QBOCommonUtility.ConnectToQBO(AccessToken, AccessTokenSecret, CompanyId);
    Customer customer = GetQBOCustomerById(AccessToken, AccessTokenSecret, CompanyId, id);
    Customer resultCustomer = new Customer();//dataService.FindById(customer) as Customer;
    if (customer != null)
    {
    bool isChanged = false;
    if (customer.DisplayName != request.Customer.DisplayName)
    {
    customer.DisplayName = request.Customer.DisplayName == null ? "" : request.Customer.DisplayName;
    customer.GivenName = request.Customer.GivenName == null ? "" : request.Customer.GivenName;
    customer.MiddleName = request.Customer.MiddleName == null ? "" : request.Customer.MiddleName;
    customer.FamilyName = request.Customer.FamilyName == null ? "" : request.Customer.FamilyName;
    isChanged = true;
    }
    if (request.Customer.PrimaryPhone != null)
    {
    if (customer.PrimaryPhone == null)
    {
    customer.PrimaryPhone = new TelephoneNumber();
    }
    if(customer.PrimaryPhone.FreeFormNumber != request.Customer.PrimaryPhone.FreeFormNumber)
    {
    customer.PrimaryPhone.FreeFormNumber = request.Customer.PrimaryPhone.FreeFormNumber == null ? "" : request.Customer.PrimaryPhone.FreeFormNumber;
    isChanged = true;
    }
    }
    if(customer.CompanyName != request.Customer.CompanyName)
    {
    customer.CompanyName = request.Customer.CompanyName == null ? "" : request.Customer.CompanyName;
    isChanged = true;
    }
    if (request.Customer.PrimaryEmailAddr != null)
    {
    if(customer.PrimaryEmailAddr == null)
    {
    customer.PrimaryEmailAddr = new EmailAddress();
    }
    if(customer.PrimaryEmailAddr.Address != request.Customer.PrimaryEmailAddr.Address)
    {
    customer.PrimaryEmailAddr.Address = request.Customer.PrimaryEmailAddr.Address == null ? "" : request.Customer.PrimaryEmailAddr.Address;
    isChanged = true;
    }
    }
    if (customer.Title != request.Customer.Title)
    {
    customer.Title = request.Customer.Title == null ? "" : request.Customer.Title;
    isChanged = true;
    }
    if(customer.Notes != request.Customer.Notes)
    {
    customer.Notes = request.Customer.Notes == null ? "" : request.Customer.Notes;
    isChanged = true;
    }

    if(isChanged)
    {
    resultCustomer = dataService.Update(customer) as Customer;
    }
    return resultCustomer;
    }
    return customer;
    }

    10.更新Invoice信息到QBO

    internal static Invoice UpdateInvoice(QBOInvoiceRequest request, Customer customer)
    {
    string AccessToken = request.AccessToken;
    string AccessTokenSecret = request.AccessTokenSecret;
    string CompanyId = request.Invoice.QBOCompanyId;
    DataService dataService = QBOCommonUtility.ConnectToQBO(AccessToken, AccessTokenSecret, CompanyId);
    Invoice invoice = dataService.FindAll(new Invoice()).Where(a => a.Id == request.Invoice.QBOId).SingleOrDefault();
    if (invoice == null)
    {
    return null;
    }
    invoice.CustomerRef.Value = customer.Id;
    invoice.TxnDate = Convert.ToDateTime(request.Invoice.InvoiceDate);

    Line line = invoice.Line[0];
    line.Amount = request.Invoice.Amount;

    var termStr = request.Invoice.Term;
    int termDays = CommonUtility.getTermDays(termStr);
    string dueDate = DateTime.Parse(request.Invoice.InvoiceDate).AddDays(termDays).ToString(Constants.FORMAT_MONTH_DAY_YEAR);
    invoice.DueDate = Convert.ToDateTime(dueDate);

    if (invoice.BillEmail == null)
    {
    invoice.BillEmail = new EmailAddress();
    invoice.BillEmail.DefaultSpecified = true;
    invoice.BillEmail.Address = request.Invoice.ContactEmail;
    }
    invoice.PrivateNote = request.Invoice.Note;

    Item item = dataService.FindAll(new Item(), 1, 1).SingleOrDefault();
    SalesItemLineDetail lineSalesItemLineDetail = new SalesItemLineDetail();
    //Line Sales Item Line Detail - ItemRef
    lineSalesItemLineDetail.ItemRef = new ReferenceType()
    {
    name = item.Name,
    Value = item.Id
    };
    //Line Sales Item Line Detail - UnitPrice
    lineSalesItemLineDetail.AnyIntuitObject = 0m;
    lineSalesItemLineDetail.ItemElementName = ItemChoiceType.UnitPrice;

    //Line Sales Item Line Detail - Qty
    lineSalesItemLineDetail.Qty = 0;
    lineSalesItemLineDetail.QtySpecified = true;

    //Line Sales Item Line Detail - TaxCodeRef
    //For US companies, this can be 'TAX' or 'NON'
    lineSalesItemLineDetail.TaxCodeRef = new ReferenceType()
    {
    Value = "NON"
    };

    //Line Sales Item Line Detail - ServiceDate
    lineSalesItemLineDetail.ServiceDate = DateTime.Now.Date;
    lineSalesItemLineDetail.ServiceDateSpecified = true;

    //Assign Sales Item Line Detail to Line Item
    line.AnyIntuitObject = lineSalesItemLineDetail;


    Invoice updateInvoice = dataService.Update(invoice);
    return updateInvoice;
    }

    11.删除QBO中的Invoice信息

    public static bool DeleteInvoice(string invoiceid, string AccessToken, string AccessTokenSecret, string CompanyId)
    {
    DataService dataService = QBOCommonUtility.ConnectToQBO(AccessToken, AccessTokenSecret, CompanyId);
    Invoice invoice = dataService.FindAll(new Invoice()).Where(a => a.Id == invoiceid).SingleOrDefault();
    Invoice updateInvoice = dataService.Delete(invoice);
    return true;
    }

    二、REST API方式连接QBO

    参考文档和API接口地址:

    https://developer.intuit.com/docs/api/accounting/invoice

    官方API测试地址:

    https://developer.intuit.com/v2/apiexplorer?apiname=V3QBO#?id=Account

    1.REST API 查询:

    public static string ExecuteV3Query(string AccessToken, string AccessTokenSecret, string CompanyId, string Query)
    {
    string encodeQuery = System.Web.HttpUtility.UrlEncode(Query);
    string uri = string.Format("https://quickbooks.api.intuit.com/v3/company/{0}/query?query={1}&minorversion=4", CompanyId, Query);

    HttpWebRequest httpWebRequest = WebRequest.Create(uri) as HttpWebRequest;
    httpWebRequest.Method = "GET";
    httpWebRequest.Accept = "application/json";
    httpWebRequest.Headers.Add("Authorization", GetDevDefinedOAuthHeader(consumerKey, consumerSecret, AccessToken, AccessTokenSecret, httpWebRequest, null));

    HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
    using(Stream data = httpWebResponse.GetResponseStream())
    {
    return new StreamReader(data).ReadToEnd();
    }
    }

    参数中的Query字符串是用来传递SQL语句的比如“select * from Invoice”

    private static string GetDevDefinedOAuthHeader(string consumerkey,string consumerSecret,string accessToken,string accessTokenSecret,HttpWebRequest webRequest,string requestBody)
    {
    OAuthConsumerContext consumerContext = new OAuthConsumerContext
    {
    ConsumerKey = consumerkey,
    SignatureMethod = SignatureMethod.HmacSha1,
    ConsumerSecret = consumerSecret,
    UseHeaderForOAuthParameters = true

    };

    //We already have OAuth tokens, so OAuth URIs below are not used - set to example.com
    OAuthSession oSession = new OAuthSession(consumerContext, "https://www.example.com", "https://www.example.com", "https://www.example.com");
    oSession.AccessToken = new TokenBase
    {
    Token = accessToken,
    ConsumerKey = consumerKey,
    TokenSecret = accessTokenSecret
    };

    IConsumerRequest consumerRequest = oSession.Request();
    consumerRequest = ConsumerRequestExtensions.ForMethod(consumerRequest, webRequest.Method);
    if(requestBody!=null)
    {
    consumerRequest = consumerRequest.Post().WithRawContentType(webRequest.ContentType).WithRawContent(System.Text.Encoding.ASCII.GetBytes(requestBody));

    }
    consumerRequest = ConsumerRequestExtensions.ForUri(consumerRequest, webRequest.RequestUri);
    consumerRequest = consumerRequest.SignWithToken();
    return consumerRequest.Context.GenerateOAuthParametersForHeader();
    }

    2.REST API 新建Invoice

    1)连接QBO的新建函数:

    public static string ExecuteV3InvoiceInsert(string AccessToken, string AccessTokenSecret, string CompanyId,string body)
    {
    string uri = string.Format("https://quickbooks.api.intuit.com/v3/company/{0}/invoice?minorversion=4", CompanyId);

    HttpWebRequest httpWebRequest = WebRequest.Create(uri) as HttpWebRequest;
    httpWebRequest.Method = "POST";
    httpWebRequest.ContentType = "application/json";
    httpWebRequest.Accept = "application/json";
    httpWebRequest.Headers.Add("Authorization", GetDevDefinedOAuthHeader(consumerKey, consumerSecret, AccessToken, AccessTokenSecret, httpWebRequest, null));

    byte[] formData = UTF8Encoding.UTF8.GetBytes(body);
    httpWebRequest.ContentLength = formData.Length;
    using (Stream postStream = httpWebRequest.GetRequestStream())
    {
    postStream.Write(formData, 0, formData.Length);
    }
    string response = string.Empty;
    try
    {
    WebResponse webResponse = httpWebRequest.GetResponse();
    using (Stream webStream = webResponse.GetResponseStream())
    {
    if (webStream != null)
    {
    using (StreamReader responseReader = new StreamReader(webStream))
    {
    response = responseReader.ReadToEnd();
    }
    }
    }
    return response;
    }
    catch(Exception ex)
    {
    return "";
    }
    }

    2)逻辑层调用ExecuteV3InvoiceInsert函数:

    internal static BOSmobileService.DataObjects.RefInvoice CreateInvoiceAPI(QBOInvoiceRequest request, Customer customer)
    {
    string AccessToken = request.AccessToken;
    string AccessTokenSecret = request.AccessTokenSecret;
    string CompanyId = request.Invoice.QBOCompanyId;
    var amount = request.Invoice.Amount;
    var invoiceDate = request.Invoice.InvoiceDate;
    var termStr = request.Invoice.Term;
    int termDays = CommonUtility.getTermDays(termStr);
    string dueDate = DateTime.Parse(invoiceDate).AddDays(termDays).ToString(Constants.FORMAT_MONTH_DAY_YEAR);
    var contactEmail = request.Invoice.ContactEmail;
    var note = request.Invoice.Note;

    string body = GetParams(invoiceDate, dueDate, note, amount.ToString(), customer.Id, contactEmail);
    string refStr = QBOCommonUtility.ExecuteV3InvoiceInsert(AccessToken, AccessTokenSecret, CompanyId, body);

    BOSmobileService.DataObjects.RefInvoice invocie = Newtonsoft.Json.JsonConvert.DeserializeObject<BOSmobileService.DataObjects.RefInvoice>(refStr);
    return invocie;
    }

    public static string GetParams(string invoiceDate, string dueDate, string note, string amount, string customerId, string contactEmail)
    {
    StringBuilder sb = new StringBuilder();
    sb.Append("{\"TxnDate\":\"");
    sb.Append(invoiceDate);
    sb.Append("\",\"DueDate\":\"");
    sb.Append(dueDate);
    sb.Append("\",\"PrivateNote\":\"");
    sb.Append(note);
    sb.Append("\",\"Line\":[{\"Amount\":");
    sb.Append(amount);
    sb.Append(",\"DetailType\": \"SalesItemLineDetail\",\"SalesItemLineDetail\": {\"ItemRef\": {\"value\": \"1\",\"name\": \"Sales\"}}}],\"CustomerRef\": {\"value\": \"");
    sb.Append(customerId);
    sb.Append("\"},\"BillEmail\": {\"Address\":\"");
    sb.Append(contactEmail);
    sb.Append("\"}}");
    return sb.ToString();
    }

    3. REST API删除Invoice

    public static bool DeleteInvoiceAPI(string invoiceid, string AccessToken, string AccessTokenSecret, string CompanyId)
    {
    StringBuilder sb = new StringBuilder();
    sb.Append("{\"Id\": \"");
    sb.Append(invoiceid);
    sb.Append("\",\"SyncToken\": \"3\"}");
    string body = sb.ToString();//string.Format("{\"Id\": \"{0}\",\"SyncToken\": \"3\"}",invoiceid);
    string refStr = QBOCommonUtility.ExecuteV3InvoiceDelete(AccessToken, AccessTokenSecret, CompanyId, body);
    return true;
    }

    public static string ExecuteV3InvoiceDelete(string AccessToken, string AccessTokenSecret, string CompanyId, string body)
    {
    string uri = string.Format("https://quickbooks.api.intuit.com/v3/company/{0}/invoice?operation=delete&minorversion=4", CompanyId);
    HttpWebRequest httpWebRequest = WebRequest.Create(uri) as HttpWebRequest;
    httpWebRequest.Method = "POST";
    httpWebRequest.ContentType = "application/json";
    httpWebRequest.Accept = "application/json";
    httpWebRequest.Headers.Add("Authorization", GetDevDefinedOAuthHeader(consumerKey, consumerSecret, AccessToken, AccessTokenSecret, httpWebRequest, null));

    byte[] formData = UTF8Encoding.UTF8.GetBytes(body);
    httpWebRequest.ContentLength = formData.Length;
    using (Stream postStream = httpWebRequest.GetRequestStream())
    {
    postStream.Write(formData, 0, formData.Length);
    }
    string response = string.Empty;
    try
    {
    WebResponse webResponse = httpWebRequest.GetResponse();
    using (Stream webStream = webResponse.GetResponseStream())
    {
    if (webStream != null)
    {
    using (StreamReader responseReader = new StreamReader(webStream))
    {
    response = responseReader.ReadToEnd();
    }
    }
    }
    return response;
    }
    catch (Exception ex)
    {
    return "Error";
    }

    }

    4. 创建Payment(创建与Invoice的Amount金额数目相对应Payment等同于把Invoice设置成Paid状态)

    public static string MarkInvoicePaid(string invoiceid, string customerId, decimal amount, string AccessToken, string AccessTokenSecret, string CompanyId)
    {
    StringBuilder sb = new StringBuilder();
    sb.Append("{\"CustomerRef\":{\"value\": \"");
    sb.Append(customerId);
    sb.Append("\"},\"TotalAmt\": ");
    sb.Append(amount.ToString());
    sb.Append(",\"Line\": [{\"Amount\": ");
    sb.Append(amount.ToString());
    sb.Append(",\"LinkedTxn\": [{\"TxnId\": \"");
    sb.Append(invoiceid);
    sb.Append("\",\"TxnType\": \"Invoice\"}]}]}");
    string body = sb.ToString();
    string response = QBOCommonUtility.ExecuteV3InvoicePayment(AccessToken, AccessTokenSecret, CompanyId, body);
    return response;
    }

    internal static string ExecuteV3InvoicePayment(string AccessToken, string AccessTokenSecret, string CompanyId, string body)
    {
    string uri = string.Format("https://quickbooks.api.intuit.com/v3/company/{0}/payment?minorversion=4", CompanyId);
    HttpWebRequest httpWebRequest = WebRequest.Create(uri) as HttpWebRequest;
    httpWebRequest.Method = "POST";
    httpWebRequest.ContentType = "application/json";
    httpWebRequest.Accept = "application/json";
    httpWebRequest.Headers.Add("Authorization", GetDevDefinedOAuthHeader(consumerKey, consumerSecret, AccessToken, AccessTokenSecret, httpWebRequest, null));

    byte[] formData = UTF8Encoding.UTF8.GetBytes(body);
    httpWebRequest.ContentLength = formData.Length;
    using (Stream postStream = httpWebRequest.GetRequestStream())
    {
    postStream.Write(formData, 0, formData.Length);
    }
    string response = string.Empty;
    try
    {
    WebResponse webResponse = httpWebRequest.GetResponse();
    using (Stream webStream = webResponse.GetResponseStream())
    {
    if (webStream != null)
    {
    using (StreamReader responseReader = new StreamReader(webStream))
    {
    response = responseReader.ReadToEnd();
    }
    }
    }
    return response;
    }
    catch (Exception ex)
    {
    return "Error";
    }
    }

  • 相关阅读:
    拷贝构造函数的用法
    虚基类的用法
    函数模板的用法,以及类外定义的注意事项
    怎么学好python?
    树状数组单点更新和区间查询
    线段树的基本操作
    快排算法的实现
    react-redux 中 connect 的常用写法
    ant-design表单处理和常用方法及自定义验证
    ionic 签名、打包
  • 原文地址:https://www.cnblogs.com/lujiangping/p/5254999.html
Copyright © 2011-2022 走看看