1

登录后,它正在生成一个哈希值,但仍然报错“发生了一些问题!再试一次”

PayUmoneySdkInitilizer.PaymentParam.Builder builder =
    new PayUmoneySdkInitilizer.PaymentParam.Builder();

builder.setAmount(10.0)
       .setTnxId("0nf7" + System.currentTimeMillis())
       .setPhone(<My phone>)
       .setProductName("product_name")
       .setFirstName(<My Name>)
       .setEmail(<My email>)
       .setsUrl("https://www.payumoney.com/mobileapp/payumoney/success.php")
       .setfUrl("https://www.payumoney.com/mobileapp/payumoney/failure.php")
       .setUdf1("").setUdf2("").setUdf3("").setUdf4("").setUdf5("")
       .setIsDebug(false)
       .setKey(<mykey>)
       .setMerchantId(<my debug merchant id>);

String tnxId="0nf7" + System.currentTimeMillis();
PayUmoneySdkInitilizer.PaymentParam paymentParam = builder.build();
String hashSequence = "<...>|"+tnxId+"|10.0|product_name|<My name>|<My email>|||||||||||salt";
String serverCalculatedHash= hashCal("SHA-512", hashSequence);
Toast.makeText(getApplicationContext(),
               serverCalculatedHash, Toast.LENGTH_SHORT).show();
paymentParam.setMerchantHash(serverCalculatedHash);
// calculateServerSideHashAndInitiatePayment(paymentParam);
PayUmoneySdkInitilizer.startPaymentActivityForResult(TrayActivity.this, paymentParam);

public static String hashCal(String type, String str) {
    byte[] hashseq = str.getBytes();
    StringBuffer hexString = new StringBuffer();
    try {
        MessageDigest algorithm = MessageDigest.getInstance(type);
        algorithm.reset();
        algorithm.update(hashseq);
        byte messageDigest[] = algorithm.digest();
        for (int i = 0; i<messageDigest.length; i++) {
            String hex = Integer.toHexString(0xFF &messageDigest[i]);
            if (hex.length() == 1) { hexString.append("0"); }
            hexString.append(hex);
        }
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } return hexString.toString();
}
4

1 回答 1

0

您在代码中使用:

.setTnxId("0nf7" + System.currentTimeMillis())

然后后来:

String tnxId="0nf7" + System.currentTimeMillis();

可能不是唯一的问题,但你真的想为这些使用两个不同的值(两次调用之间的时间可能会改变)吗?你不想tnxId在两种情况下都一样吗?


TransactionIdProvider.java:

import java.util.Locale;

public class TransactionIdProvider {

    private final static String DEFAULT_PREFIX = "ID";

    // Convenient prime number for incrementing the counter
    private final static long ID_ADD = 0xF0AD;  // "f*ck off and die"

    // 64b counter with non-trivial start value
    private static long idCounter = 0x0101F00DDEADBEEFL;

    /**
     * Returns ID consisting of prefix string and 64b counter interleaved
     * with 32b per-4s-timestamp.
     * 
     * May produce identical ID (collision) when:
     * 1) class is reloaded within 4s
     *    (to fix: serialize "idCounter" upon shutdown/restart of VM, or
     *    modify prefix per start of VM)
     * 2) more than 2^64 IDs are requested within 4s (no fix, unexpected)
     * 3) more than 2^64 IDs are requested after cca. 550 years.
     *    (no fix, unexpected)
     * 4) more than one static instance of TransactionIdProvider is used
     *    (two or more VMs running the app) (to fix put different prefix in
     *    every VM/server running this)
     * 
     * Length of returned ID is prefix.length() + 24 alphanumeric symbols.
     */
    public static synchronized String getNewId(final String prefix) {
        idCounter += ID_ADD;    // increment counter
        // get 32b timestamp per ~4s (millis/4096) (good for ~550 years)
        final int timeStamp = (int)(System.currentTimeMillis()>>12);
        final int idPart1 = (int)(idCounter>>32);
        final int idPart2 = (int)(idCounter);
        return String.format(Locale.US, "%s%08X%08X%08X",
                             prefix, idPart1, timeStamp, idPart2);
    }

    public static String getNewId() {
        return getNewId(DEFAULT_PREFIX);
    }

}

不确定这个有多少可用,以及 ID 是否可能这么长。您可以随意使用/修改它。

我也想知道,我是否没有忘记一些重要的事情,但什么都想不起来。

这一款的安全性还是比较弱的,在4s的时间内ID会像简单的加法一样,但至少不会产生1、2、3...系列。


确实找到了一些 SDK 文档,看起来 txnId 可能有 25 个字符长,所以你只有 1 个字符作为前缀。或者减少时间戳,使用%07X格式和掩码值0x0FFFFFFF,这将使它每~34年重复一次-> 2个字母作为前缀。或者将 counter 更改为 32b int,应该仍然绰绰有余,除非您预计每秒有数千笔交易->这将删除 8 个字符。或者 base32/base64 整个 ID 来缩短它(取决于什么字母对内容是合法的)......

或者其他什么……已经花了足够的时间。聘请专业人士。

于 2016-11-10T15:34:55.343 回答