Android Studio:使用 Mercado Pago 透明结账

Android Studio: Transparent checkout using Mercado Pago

我正在尝试在 Android 中首次实现 Mercado Pago 的透明结账。

我已经下载了https://github.com/mercadopago/px-android中提供的最新版SDK,并在模拟器中正常运行

在上面提到的GitHub页面中,我们已经解释了如何用一行代码实现Mercado Pago的结账:

new MercadoPagoCheckout.Builder("public_key", "checkout_preference_id")
    .build()
    .startPayment(activityOrContext, requestCode);

我们可以在 public_key 的凭据网页中获取。但是 String checkout_preference_id 我不知道如何创建它,尽管他们在 GitHub 网页的末尾展示了如何创建它。

创建您的偏好 ID

curl -X POST \
     'https://api.mercadopago.com/checkout/preferences?access_token=ACCESS_TOKEN' \
     -H 'Content-Type: application/json' \
     -d '{
           "items": [
               {
               "title": "Dummy Item",
               "description": "Multicolor Item",
               "quantity": 1,
               "currency_id": "ARS",
               "unit_price": 10.0
               }
           ],
           "payer": {
               "email": "payer@email.com"
           }
     }'

我尝试在 checkout_preference_id 中随机添加一个 String,但没有成功。只有 Mercado Pago 示例应用程序中的 String 有效。

private static final String DUMMY_PREFERENCE_ID = "243962506-0bb62e22-5c7b-425e-a0a6-c22d0f4758a9";

Mercado Pago 示例应用程序中介绍的所有其他实施方式都需要伪造的付款确认。

如果有人能展示一些如何创建变量 checkout_preference_id 并将其传递到 Mercado Pago 支付的主要命令中的代码,我将不胜感激。

编辑

如果有人能给我们一个非伪造付款确认示例,我也很感激。

我想 checkout_preference_id 可以通过市场网站访问,或者可以使用 Android 的网络服务创建 curl。然后,对我来说还是个谜。

关于使用 MercadoPago 的替代支付方式,我们还有其他论点要通过:

new MercadoPagoCheckout.Builder("public_key", checkoutPreference, paymentConfiguration)
                .build()
                .startPayment(activityOrContext, requestCode);

其中 checkoutPreference 允许您创建 自定义物品 进行销售。

final Item item = new Item.Builder("Product Title", 1, new BigDecimal(12.3)).setDescription("Product Description").build();
CheckoutPreference checkoutPreference = new CheckoutPreference.Builder(Sites.BRASIL, "a@a.a", Collections.singletonList(item)).setDefaultInstallments(1).build();

paymentConfiguration实现了伪造的支付确认.

PaymentConfiguration paymentConfiguration = new PaymentConfiguration.Builder(new MyPaymentProcessor()).build();

其中 class MyPaymentProcessor() 和它所依赖的其他 class 可以在 GitHub 示例中找到。

val queue = Volley.newRequestQueue(this)

    val strJson = "{\n" +
            "           \"items\": [\n" +
            "               {\n" +
            "               \"title\": \"Item\",\n" +
            "               \"description\": \"Multicolor Item\",\n" +
            "               \"quantity\": 1,\n" +
            "               \"currency_id\": \"BRL\",\n" +
            "               \"unit_price\": 35.0\n" +
            "               }\n" +
            "           ],\n" +
            "           \"payer\": {\n" +
            "\t\t    \"name\": \"Núbia\",\n" +
            "\t\t    \"surname\": \"Macedo\",\n" +
            "\t\t    \"email\": \"leann@gmail.com\",\n" +
            "\t\t    \"date_created\": \"2015-06-02T12:58:41.425-04:00\",\n" +
            "\t\t    \"phone\": {\n" +
            "\t\t      \"area_code\": \"\",\n" +
            "\t\t      \"number\": \"880.402.7555\"\n" +
            "\t\t    },\n" +
            "\t\t    \"identification\": {\n" +
            "\t\t      \"type\": \"DNI\",\n" +
            "\t\t      \"number\": \"123456789\"\n" +
            "\t\t    },\n" +
            "\t\t    \"address\": {\n" +
            "\t\t      \"street_name\": \"Núbia Viela\",\n" +
            "\t\t      \"street_number\": 25598,\n" +
            "\t\t      \"zip_code\": \"8972\"\n" +
            "\t\t    }\n" +
            "\t\t  }\n" +
            "     }"

    val obj = JSONObject(strJson)

    //val url = "https://api.mercadopago.com/checkout/preferences"
    val url = "https://api.mercadopago.com/checkout/preferences?access_token=TEST-XXXXXXXXXXXX-XXXXXXX-XXXXXXXXXXXXXXXXXXX-XXXXXXXXXXXXXX"
    val stringRequest = object : JsonObjectRequest(Method.POST, url, obj,
        Response.Listener<JSONObject> {response ->
            val checkoutPreferenceId: String= response.getString("id")
            MercadoPagoCheckout.Builder("TEST-XXXXXXXX-XXXX-XXXX-XXXXX-XXXXXXXXXX", checkoutPreferenceId)
                .build().startPayment(this, REQUEST_CODE)
        },
        Response.ErrorListener { error ->
            val erros = error.toString()
            val teste1 = "sdsds"
            val teste12 = "sdsds"
            val teste13 = "sdsds"
        }

    ) {
        @Throws(AuthFailureError::class)
        override fun getHeaders(): Map<String, String> {
            val headers = HashMap<String, String>()
            headers["Content-Type"] = "application/json"
            return headers
        }

    }

    val policy = DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 10, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)
    stringRequest.retryPolicy = policy
    queue.add(stringRequest)

别忘了交换你的 access_token。

Json 示例:https://www.mercadopago.com.br/developers/pt/guides/payments/web-checkout/personalization/

包:

implementation 'com.mercadopago.android.px:checkout:4.5.2'
implementation 'com.android.volley:volley:1.1.0'

有助于理解如何生成 String checkout_preference_id.

您将在下方看到通过 MercadoPago 接收付款所需的最低代码。

首先,你必须在 build.gradle (Module: app)

中添加依赖
// Dealing with HTTP internet connection
implementation 'com.android.volley:volley:1.1.1'

//Dealing with MercadoPago SDK and dependencies
implementation 'com.mercadopago.android.px:checkout:4.0.+'

有些人建议在 Manifest

中添加 internet 权限
<uses-permission android:name="android.permission.INTERNET" />

接下来,您需要创建一个 JSONObject,有多种方法可以实现。

这样:

    StringBuilder strjsonobj = new StringBuilder();
    String strJson = "{\n" +
            "           \"items\": [\n" +
            "               {\n" +
            "               \"title\": \"Item\",\n" +
            "               \"description\": \"Multicolor Item\",\n" +
            "               \"quantity\": 1,\n" +
            "               \"currency_id\": \"BRL\",\n" +
            "               \"unit_price\": 35.0\n" +
            "               }\n" +
            "           ],\n" +
            "           \"payer\": {\n" +
            "\t\t    \"name\": \"Núbia\",\n" +
            "\t\t    \"surname\": \"Macedo\",\n" +
            "\t\t    \"email\": \"leann@gmail.com\",\n" +
            "\t\t    \"date_created\": \"2015-06-02T12:58:41.425-04:00\",\n" +
            "\t\t    \"phone\": {\n" +
            "\t\t      \"area_code\": \"\",\n" +
            "\t\t      \"number\": \"880.402.7555\"\n" +
            "\t\t    },\n" +
            "\t\t    \"identification\": {\n" +
            "\t\t      \"type\": \"DNI\",\n" +
            "\t\t      \"number\": \"123456789\"\n" +
            "\t\t    },\n" +
            "\t\t    \"address\": {\n" +
            "\t\t      \"street_name\": \"Núbia Viela\",\n" +
            "\t\t      \"street_number\": 25598,\n" +
            "\t\t      \"zip_code\": \"8972\"\n" +
            "\t\t    }\n" +
            "\t\t  }\n" +
            "     }";

    strjsonobj.append(strJson);
    JSONObject jsonObject = new JSONObject();
    try {
        jsonObject = new JSONObject(strjsonobj.toString());
        Log.i("debinf MainAct", "object is : "+jsonObject);
    } catch (JSONException e) {
        e.printStackTrace();
    }

或者这样:

    JSONObject jsonObject = new JSONObject();
    final JSONObject itemJSON = new JSONObject();
    final JSONObject payerJSON = new JSONObject();
    JSONArray itemJsonArray = new JSONArray();
    try {

        itemJSON.put("title", "Dummy Item");
        itemJSON.put("description", "Multicolor Item");
        itemJSON.put("quantity", 1);
        itemJSON.put("currency_id", "BRL");
        itemJSON.put("unit_price", 2.10);

        itemJsonArray.put(itemJSON);

        JSONObject phoneJSON = new JSONObject();
        phoneJSON.put("area_code", "");
        phoneJSON.put("number", "880.402.7555");
        JSONObject idJSON = new JSONObject();
        idJSON.put("type", "DNI");
        idJSON.put("number", "123456789");
        JSONObject addressJSON = new JSONObject();
        addressJSON.put("street_name", "Núbia Viela");
        addressJSON.put("street_number", 25598);
        addressJSON.put("zip_code", "8972");

        payerJSON.put("name", "Núbia");
        payerJSON.put("surname", "Macedo");
        payerJSON.put("email", "leann@gmail.com");
        payerJSON.put("date_created", "2015-06-02T12:58:41.425-04:00");
        payerJSON.put("phone", phoneJSON);
        payerJSON.put("identification", idJSON);
        payerJSON.put("address", addressJSON);


        jsonObject.put("items", itemJsonArray);
        jsonObject.put("payer", payerJSON);
    } catch (JSONException e) {
        e.printStackTrace();
    }

MercadoPago 建议尽可能多地发送有关付款人的信息,以提高付款转化率。但是你可以发送尽可能少的问题。

除此之外,您还可以对 JSONObject 中的其他内容进行个性化设置,例如 here

现在,让我们创建变量 String checkout_preference_id。为此,我使用了 volley 方法。当MercadoPago服务器发回我们的变量时,我们会自动开始支付。

    RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this);
    final String url = "https://api.mercadopago.com/checkout/preferences?access_token="+ACCESS_TOKEN_SANDBOX;
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, jsonObject, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            try {
                Log.i("debinf MainAct", "response JSONObject: "+response);
                String checkoutPreferenceId = response.getString("id");
                new MercadoPagoCheckout.Builder(PUBLIC_KEY_SANDBOX, checkoutPreferenceId).build().startPayment(MainActivity.this,REQUEST_CODE);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.i("debinf MainAct", "response ERROR: "+error.networkResponse.allHeaders);
        }
    }){
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json");
            return headers;
        }
    };
    requestQueue.add(jsonObjectRequest);

使用startPayment发送的REQUEST_CODE获取onActivityResult中的结账结果。

@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
    if (requestCode == REQUEST_CODE) {
        if (resultCode == MercadoPagoCheckout.PAYMENT_RESULT_CODE) {
            final Payment payment = (Payment) data.getSerializableExtra(MercadoPagoCheckout.EXTRA_PAYMENT_RESULT);
            ((TextView) findViewById(R.id.mp_results)).setText("Resultado del pago: " + payment.getStatus());
            //Done!
        } else if (resultCode == RESULT_CANCELED) {
            if (data != null && data.getExtras() != null
                && data.getExtras().containsKey(MercadoPagoCheckout.EXTRA_ERROR)) {
                final MercadoPagoError mercadoPagoError =
                    (MercadoPagoError) data.getSerializableExtra(MercadoPagoCheckout.EXTRA_ERROR);
                ((TextView) findViewById(R.id.mp_results)).setText("Error: " +  mercadoPagoError.getMessage());
                //Resolve error in checkout
            } else {
                //Resolve canceled checkout
            }
        }
    }
}

就是这样!请随意改进上面的代码。主要是关于安全问题。