【问题标题】:How to integerate Mpesa Api with android如何将 Mpesa Api 与 android 集成
【发布时间】:2015-11-26 05:17:39
【问题描述】:

我正在制作贷款应用程序。因为我住在非洲以外,所以我被困在如何集成 MPESA 上。

这里是链接PESAPI。我已经完成了第 3 步,但现在我不知道下一步该做什么。

Q 1) 我可以将它与我的贷款应用 android 集成吗?

Q 2) 下一步该怎么做,请指导我,我从最后一个弱者开始就被困在这个问题上。

【问题讨论】:

  • 我正在为我住在非洲的客户做这个
  • 您可以在此时调用托管 API 的 Web 应用程序并实现相同的目的。
  • @nafeesahmed 你找到解决方案了吗。我的头在燃烧男人

标签: java php android


【解决方案1】:

如果您仍然感兴趣,Safaricom 最近推出了REST based interface 用于使用 MPesa API。他们在那里有文档,关于如何使用它的很好的教程可以在here 找到。为了在您的应用上使用,您需要一个后端接口来充当 MPesa 的中介,因为它们的大多数 API 都是异步的。

【讨论】:

    【解决方案2】:

    Pesa pi 不能用于预期目的。 pesapi 所做的是从您的 android 手机获取确认消息并将该消息推送到您的应用程序。

    在此上下文中的消息是 mpesa 在通过 lipa na mpesa 完成付款并支付账单后发送到收款人的注册手机号码的消息。

    Mutwiri 的建议是让您从 mpesa 网站 http://www.safaricom.co.ke/business/sme/m-pesa-payment-solutions/m-pesa-api 获取 API 并为您的应用程序构建一个中间件。

    提示:查看 B2C 和 C2B-paybill 和 lipa na mpesa 文档。

    【讨论】:

      【解决方案3】:

      M-PESA API 在线结账 Java / Android 如何

      在 M-PESA API 发布之后,您需要创建一个 Web 服务客户端来执行 SOAP 请求并处理来自 API 调用的响应

      我将为致力于集成现有 Java 应用程序的 Java 开发人员提供快速入门指南。

      先决条件

      JDK 7 或最新版本

      说明步骤

      从 safaricom 网站下载完整的 M-PESA API 指南 通读开发者指南 C2B_OnlineCheckout_V2.0.doc 生成 JAX-WS 工件。您的客户端将使用此 API 访问已发布的 Web 服务。 生成 JAX-WS 工件 我们将使用 wsimport 工具来解析签出的 WSDL 文件并生成所需的文件。

      mkdir src
      
      wsimport -XadditionalHeaders -clientjar safaricom-lipanampesa-onlinecheckout-wsdl.jar -s src -p ke.co.makara.integration.mpesa.lnmocheckout http://safaricom.co.ke/mpesa_online/lnmo_checkout_server.php?wsdl
      

      检查 wsimport --help 以了解上述选项; 请注意生成的工件的包目录。 WSDL 托管在 lipa na M-PESA 端点上。为此,我们使用生产 URL。 -clientjar 选项,Java 7 中的新选项,简化了事情。否则,您将不得不使用 -wsdllocation /META-INF/wsdl/Checkout.wsdl 选项。并在之后复制 META-INF 中的 wsdl 以减轻 Java 6 wsimport 限制。请参阅下面的限制。 可选择创建源 jar 在 src 文件夹中运行命令。

      jar cvf safaricom-lipanampesa-onlinecheckout-source-wsdl.jar ke/
      

      接下来,我们使用 Web 服务工件从 Web 服务客户端调用 Web 服务。

      生成的工件

      服务端点接口 (SEI) - LNMOPortType.java 服务类 - LnmoCheckoutService.java 如果 WSDL 中存在 wsdl:fault,则 Exception 类 从模式类型映射的 Java 类,例如 ProcessCheckOutRequest.java 如果 WSDL 中存在 wsdl:message,则异步响应 bean 例如 ProcessCheckOutResponse.java

      网络服务客户端

      接下来,我们使用 Web 服务工件从 Web 服务客户端调用 Web 服务。 这可以是从前端调用的 servlet。超出范围。为简单起见,我将创建一个 java 类 ~ 一个独立的控制台

      创建一个 java 类说 LNMOCheckoutTester 在 Java 客户端应用程序中,创建 LnmoCheckoutService 服务的实例

      LnmoCheckoutService lnmoCheckoutService = new LnmoCheckoutService(); // lina na mpesa online checkout instance
      

      Service 类将在构建期间创建。 使用 getLnmoCheckout() 方法从服务中获取到服务的代理

      LNMOPortType soap = lnmoCheckoutService.getLnmoCheckout();
      

      端口携带协议绑定和服务端点地址信息。 配置服务端点 在 javax.xml.ws.BindingProvider 接口上配置请求上下文属性

      ((BindingProvider)soap).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url + "lnmo_checkout_server.php"); // specifying this property on the RequestContext
      

      JAX-WS 提供对服务端点操作的动态调用的支持。 我将 Web 服务 url 存储在数据库中,并将 wsdl 端点附加到该 url。这会在运行时配置端点。 撰写我们的客户请求 M-PESA 结帐消息 这是消息负载

      ProcessCheckOutRequest checkOutRequest = objFactory.createProcessCheckOutRequest();
        checkOutRequest.setMERCHANTTRANSACTIONID("54635469064");
        checkOutRequest.setREFERENCEID("TD346534GH");
        checkOutRequest.setAMOUNT(13300);
        checkOutRequest.setMSISDN("0721XXXXXX");
        checkOutRequest.setENCPARAMS("");
        checkOutRequest.setCALLBACKURL("https://makara.co.ke:8443/odt/checkout");
        checkOutRequest.setCALLBACKMETHOD("GET");
        checkOutRequest.setTIMESTAMP(String.valueOf(date.getTime()));
      

      配置请求标头 按照 Safaricom 文档中的业务规则构建密码。见附件代码。 对于字符串的merchantId、String passkey、Date requestTimeStamp;将连接的字符串转换为字节,对字节进行哈希处理以获得任意二进制数据并将二进制数据转换为字符串使用 base64

      CheckOutHeader requestHeader = objFactory.createCheckOutHeader();
        requestHeader.setMERCHANTID(MERCHANT_ID);
        Date timestamp = new Date();
        String encryptedPassword = getEncryptedPassword(MERCHANT_ID, PASSKEY, timestamp);
        requestHeader.setPASSWORD(encryptedPassword.toUpperCase());
        requestHeader.setTIMESTAMP(String.valueOf(timestamp.getTime()));
      

      使用基于 dispatch stab 的客户端调用服务端点 soap.processCheckOut(checkOutRequest, requestHeader); 根据您的业务需求处理来自服务的响应消息

        ProcessCheckOutResponse checkOutResponse = new ProcessCheckOutResponse();
        checkOutResponse.getRETURNCODE();
        checkOutResponse.getDESCRIPTION();
        checkOutResponse.getTRXID();
        checkOutResponse.getCUSTMSG();
      

      跟踪 SOAP 流量

      调试 Web 服务应用程序的一个常见步骤是检查请求和响应 SOAP 消息 配置客户端以使用 JAX-WS 转储请求和响应 System.setProperty("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true");

      源代码

      /*
       * LNMOCheckoutTester.java
       *
       * Nov 20, 2016 Joseph Makara -  Created File to tester Lina Na M-PESA Online checkout
       *
       *
       */
      package testMe;
      
      import java.io.*;
      import java.security.*;
      import java.util.*;
      import javax.net.ssl.*;
      import javax.xml.ws.*;
      import ke.co.makara.integration.mpesa.lnmocheckout.*;
      import org.apache.commons.codec.binary.*;
      
      /**
       * @author Joseph Makara
       *
       */
      public class LNMOCheckoutTester {
      
       private static final String PASSKEY = "234fdsghfsg5654dgfhgf6dsfdsafsd43dgfhdgfdgfh74567";
       private static final String MERCHANT_ID = "678fsgd54354";
       private static final String REFERENCE_ID = "";
       private static final String ENDPOINT_URL = "https://safaricom.co.ke/mpesa_online/";
       private static final String CALLBACK_URL = "https://makara.co.ke:8443/odt/checkout";
       private static final String CALLBACK_METHOD = "GET";
      
      
       static {
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
         @Override
         public boolean verify(String hostname, SSLSession session) {
          if (hostname.equals("safaricom.co.ke")) return true;
          return false;
         }
        });
       }
      
       /**
        * @param args
        */
       public static void main(String[] args) {
      
        LNMOPortType soap = outBoundLNMOCheckout(ENDPOINT_URL);
      
        ObjectFactory objFactory = new ObjectFactory();
      
        CheckOutHeader requestHeader = objFactory.createCheckOutHeader();
        requestHeader.setMERCHANTID(MERCHANT_ID);
        Date timestamp = new Date();
        String encryptedPassword = getEncryptedPassword(MERCHANT_ID, PASSKEY, timestamp);
        requestHeader.setPASSWORD(encryptedPassword);
        requestHeader.setTIMESTAMP(String.valueOf(timestamp.getTime()));
      
        ProcessCheckOutRequest checkOutRequest = objFactory.createProcessCheckOutRequest();
        checkOutRequest = processCheckOut(timestamp);
      
        soap.processCheckOut(checkOutRequest, requestHeader);
      
        ProcessCheckOutResponse checkOutResponse = new ProcessCheckOutResponse();
        checkOutResponse.getRETURNCODE();
        checkOutResponse.getDESCRIPTION();
        checkOutResponse.getTRXID();
        checkOutResponse.getENCPARAMS();
        checkOutResponse.getCUSTMSG();
       }
      
       private static ProcessCheckOutRequest processCheckOut(Date date){
      
        ProcessCheckOutRequest checkOutRequest = new ProcessCheckOutRequest();
        checkOutRequest.setMERCHANTTRANSACTIONID("54635469064");
        checkOutRequest.setREFERENCEID("TD346534GH");
        checkOutRequest.setAMOUNT(3.45);
        checkOutRequest.setMSISDN("0721826284");
        checkOutRequest.setENCPARAMS("");
        checkOutRequest.setCALLBACKURL(CALLBACK_URL);
        checkOutRequest.setCALLBACKMETHOD(CALLBACK_METHOD);
        checkOutRequest.setTIMESTAMP(String.valueOf(date.getTime()));
      
        return  checkOutRequest;
       }
      
       /**
        * Convert the concatenated string to bytes
        * Hash the bytes to get arbitary binary data
        * Convert the binary data to string use base64
        *
        * @param merchantId
        * @param passkey
        * @param date
        * @return
        */
       private static String getEncryptedPassword(String merchantId, String passkey, Date date) {
        String encodedPassword = null;
        StringBuilder builder = new StringBuilder(merchantId)
        .append(passkey)
        .append(date.getTime());
      
        try {
         String sha256 = getSHA256Hash(builder.toString());
         return new String(Base64.encodeBase64(sha256.getBytes("UTF-8")));;
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) {
         ex.printStackTrace();
        }
      
        return encodedPassword;
       }
      
       private static LNMOPortType outBoundLNMOCheckout(String url) {
        System.setProperty("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true");
        LnmoCheckoutService lnmoCheckoutService = new LnmoCheckoutService();
        LNMOPortType soap = lnmoCheckoutService.getLnmoCheckout();
      
        ((BindingProvider)soap).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
         url + "lnmo_checkout_server.php");
      
        return soap;
       }
      
       private static String getSHA256Hash(String input) throws NoSuchAlgorithmException {
        MessageDigest mDigest = MessageDigest.getInstance("SHA-256");
        byte[] result = mDigest.digest(input.getBytes());
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < result.length; i++) {
         sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
        }
        return sb.toString();
       }
      
      }
      

      样品肥皂请求

      [HTTP request - https://safaricom.co.ke/mpesa_online/lnmo_checkout_server.php]---
      Accept: text/xml, multipart/related
      Content-Type: text/xml; charset=utf-8
      SOAPAction: ""
      User-Agent: JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e
      <?xml version="1.0" ?>
      <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
          <S:Header>
              <ns2:CheckOutHeader xmlns:ns2="tns:ns">
                  <MERCHANT_ID>F2678987M</MERCHANT_ID>
                  <PASSWORD>QQFSOITZB5OJMJTW073/SCWLN5WMDL6LO0FP6DJZ8TQ=</PASSWORD>
                  <TIMESTAMP>1479116220855</TIMESTAMP>
              </ns2:CheckOutHeader>
          </S:Header>
          <S:Body>
              <ns2:processCheckOutRequest xmlns:ns2="tns:ns">
                  <MERCHANT_TRANSACTION_ID>54635469064</MERCHANT_TRANSACTION_ID>
                  <REFERENCE_ID>TD346534GH</REFERENCE_ID>
                  <AMOUNT>3.45</AMOUNT>
                  <MSISDN>0721826284</MSISDN>
                  <ENC_PARAMS></ENC_PARAMS>
                  <CALL_BACK_URL>https://makara.co.ke:8443/odt/checkout</CALL_BACK_URL>
                  <CALL_BACK_METHOD>lnmo</CALL_BACK_METHOD>
                  <TIMESTAMP>1479116220855</TIMESTAMP>
              </ns2:processCheckOutRequest>
          </S:Body>
      </S:Envelope>
      

      您只需联系 Safaricom 即可获取 Demo 测试组织详细信息(商家 ID 和密码)

      Client jar

      Source code

      【讨论】:

      • 这不能在android应用程序中使用,因为在android中没有找到一些关键的java库
      • 你真的在安卓应用中测试过吗?
      【解决方案4】:

      M-Pesa API 目前是一个 SOAP API,而 SOAP 不是 Android 原生的,因此要将 API 集成到您的应用程序中需要大量工作。我编写 Chowder 是为了帮助开发人员轻松处理 M-Pesa,这就是你所要做的:

      //Add a new dependency
      dependencies {
          compile 'com.toe.chowder:chowder:0.7.6'
      }
      

      创建一个 Chowder 实例:

      //You can create a single global variable for Chowder like this
      Chowder chowder = new Chowder(YourActivity.this, PAYBILL_NUMBER, PASSKEY, this);
      
      //You can also add your callback URL using this constructor
      Chowder chowder = new Chowder(YourActivity.this, PAYBILL_NUMBER, callbackUrl ,PASSKEY, this);
      

      处理您的付款:

      //You can then use processPayment() to process individual payments
      chowder.processPayment(amount, phoneNumber, productId);
      

      确认付款:

      chowder.checkTransactionStatus(PAYBILL_NUMBER, transactionId);
      

      还有更多示例代码和测试 Paybill 号码和密码here

      【讨论】:

      • 如何获得这个密码?
      【解决方案5】:

      这看起来像一年前,但如果仍然没有找到解决方案,您可以看看这个。

      https://bitbucket.org/mwanzias/mpesaonlinecheckout/downloads/README.md

      从这里您将能够从 android 应用程序直接发布到执行 mpesa 通信的后端系统。

      此处描述的演示提供在线结帐功能,如果您希望将其扩展到 B2C、B2B 和 C2B 通知,那么您可以联系所有者。

      您还可以查看以下内容,看看您是否可以分叉和调整它。

      https://github.com/aksalj/pesajs

      【讨论】:

      • 所以你为这项服务收费
      • Kinene,不结帐,除非你会使用我的服务器,但如果你喜欢它,你会得到它供自己使用
      • 如何在android中实现你的jar?我可以看到一个例子。如何下载 jar,将其安装在我的项目中并使用它?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-18
      • 1970-01-01
      • 2017-04-27
      • 2015-01-16
      • 1970-01-01
      • 2013-11-30
      相关资源
      最近更新 更多