开发者

Paypal Java SDK - trying to create encrypted button - doesn't work, can't find documentation

I recently got the book "Pro Paypal E-Commerce" by Damon Williams. Its a 2007 copy, so its to be expected that some things, like the code, would change over time.

I'm trying to get this code below to work. I downloaded the paypal_base.jar file and also the paypal_wpstoolkit.jar and put them into my lib folder under jakarta-tomcat (where all my other jars are). I'm having trouble compiling the code.

This code example comes from the book and also http://en.csharp-online.net/Encrypted_Website_Payments%E2%80%94Using_the_PayPal_Java_SDK

I modified it slightly.

import com.paypal.sdk.profiles.EWPProfile;
import com.paypal.sdk.profiles.ProfileFactory;

import com.paypal.wpstoolkit.services.EWPServices;

import com.paypal.sdk.exceptions.PayPalException;


    public class PaypalTest {


      // path to your PKCS12 file
      public static final String PKCS12 = "./Certs/my_pkcs12.p12";

      // path to PayPal's public certificate
      public static final String PAYPAL_CERT = "./Certs/paypal_cert_pem.txt";

      // use https://www.sandbox.paypal.com if testing
      //public static final String URL = "https://www.paypal.com";
      public static final String URL = "https://sandbox.paypal.com";

      public static void main (String args[]) {

        // Check to see if the user provided a password
        if (args.length != 1) {
          System.out.println("You must provide a password.");
          System.exit(0);
        }

        // password used to encrypt your PKCS12 files
        // obtained from the command line
        String USER开发者_如何学Python_PASSWORD = args[0];


        // First we will create the EWPProfile object
        try {
          com.paypal.sdk.profiles.EWPProfile ewpProfile = ProfileFactory.createEWPProfile();

          ewpProfile.setCertificateFile(PKCS12);
          ewpProfile.setPayPalCertificateFile(PAYPAL_CERT);
          ewpProfile.setPrivateKeyPassword(USER_PASSWORD);
          ewpProfile.setUrl(URL);

          String buttonParameters = "cmd=_xclick\nbusiness=buyer@hotmail.com\nitem_name=vase\nitemprice=25.00";

          // Next we will create the EWPServices object
          // and tell it which EWPProfile object to use
          EWPServices ewpServices = new EWPServices();
          ewpServices.setEWPProfile(ewpProfile);

          // Finally we are ready to call the method to perform the button encryption
          String encryptedButton = ewpServices.encryptButton(buttonParameters.getBytes());

          System.out.println(encryptedButton);
        } catch (PayPalException ppe) {
          System.out.println("An exception occurred when creating the button.");
          ppe.printStackTrace();
        }       

    }

}//class    

The errors I'm getting during compilation are as follows -

java:51: cannot find symbol
symbol: method setEWPProfile(com.paypal.sdk.profiles.EWPProfile)
location: class com.paypal.wpstoolkit.services.EWPServices
ewpServices.setEWPProfile(ewpProfile);


java:55: encryptButton(byte[],java.lang.String,java.lang.String.,java.lang.String.,java.lang.String) in com.paypal.wpstoolkit.services.EWPServices cannot be applied to (byte[])
ewpServices.encryptButton(buttonParameters.getBytes());

The paypal_base jar only has NVPCallerServices.class in it, and not EWPServices. EWPServices is in the wpstoolkit jar.

How do I fix my errors? I'm having trouble finding documentation on the paypal classes.


The updated Java SDK + API documenatation can be found here:

https://cms.paypal.com/cms_content/US/en_US/files/developer/PP_Java_NVP_SDK.zip

Extract that .zip and open docs/index.html

That is where you can find all of the API documentation. It looks like you are trying to make calls to methods that no longer exist. Have a look through the new classes and see what will work for you.


Looks like with the newer API's Paypal want you to have all button code generated from their web service, as they seem to have removed the EWPService class from the SDK. But then I noticed they still provide the client side utility with with you can manually generate the code here. After a little tweaking, I got the code in there to do what I needed (encrypt an upload cart button locally).

Assuming you use Java 5+, just make sure you this and this in your classpath. Now the code isn't perfect, as it contains a bunch of deprecated methods, but for such a trivial task as encrypting the button code, it works just fine.

public String getButtonEncryptionValue(String _data,
        String _privateKeyPath, String _certPath, String _payPalCertPath,
        String _keyPass) throws IOException, CertificateException,
        KeyStoreException, UnrecoverableKeyException,
        InvalidAlgorithmParameterException, NoSuchAlgorithmException,
        NoSuchProviderException, CertStoreException, CMSException {
    _data = _data.replace(',', '\n');
    CertificateFactory cf = CertificateFactory.getInstance("X509", "BC");

    // Read the Private Key
    KeyStore ks = KeyStore.getInstance("PKCS12", "BC");
    ks.load(new FileInputStream(_privateKeyPath), _keyPass.toCharArray());

    String keyAlias = null;
    Enumeration<String> aliases = ks.aliases();
    while (aliases.hasMoreElements()) {
        keyAlias = aliases.nextElement();
    }

    PrivateKey privateKey = (PrivateKey) ks.getKey(keyAlias,
            _keyPass.toCharArray());

    // Read the Certificate
    X509Certificate certificate = (X509Certificate) cf
            .generateCertificate(new FileInputStream(_certPath));

    // Read the PayPal Cert
    X509Certificate payPalCert = (X509Certificate) cf
            .generateCertificate(new FileInputStream(_payPalCertPath));

    // Create the Data
    byte[] data = _data.getBytes();

    // Sign the Data with my signing only key pair
    CMSSignedDataGenerator signedGenerator = new CMSSignedDataGenerator();

    signedGenerator.addSigner(privateKey, certificate,
            CMSSignedDataGenerator.DIGEST_SHA1);

    ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>();
    certList.add(certificate);
    CertStore certStore = CertStore.getInstance("Collection",
            new CollectionCertStoreParameters(certList));
    signedGenerator.addCertificatesAndCRLs(certStore);

    CMSProcessableByteArray cmsByteArray = new CMSProcessableByteArray(data);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    cmsByteArray.write(baos);
    System.out.println("CMSProcessableByteArray contains ["
            + baos.toString() + "]");

    CMSSignedData signedData = signedGenerator.generate(cmsByteArray, true,
            "BC");

    byte[] signed = signedData.getEncoded();

    CMSEnvelopedDataGenerator envGenerator = new CMSEnvelopedDataGenerator();
    envGenerator.addKeyTransRecipient(payPalCert);
    CMSEnvelopedData envData = envGenerator.generate(
            new CMSProcessableByteArray(signed),
            CMSEnvelopedDataGenerator.DES_EDE3_CBC, "BC");

    byte[] pkcs7Bytes = envData.getEncoded();

    return new String(DERtoPEM(pkcs7Bytes, "PKCS7"));

}

public static byte[] DERtoPEM(byte[] bytes, String headfoot) {
    ByteArrayOutputStream pemStream = new ByteArrayOutputStream();
    PrintWriter writer = new PrintWriter(pemStream);

    byte[] stringBytes = Base64.encode(bytes);

    System.out.println("Converting " + stringBytes.length + " bytes");

    String encoded = new String(stringBytes);

    if (headfoot != null) {
        writer.print("-----BEGIN " + headfoot + "-----\n");
    }

    // write 64 chars per line till done
    int i = 0;
    while ((i + 1) * 64 < encoded.length()) {
        writer.print(encoded.substring(i * 64, (i + 1) * 64));
        writer.print("\n");
        i++;
    }
    if (encoded.length() % 64 != 0) {
        writer.print(encoded.substring(i * 64)); // write remainder
        writer.print("\n");
    }
    if (headfoot != null) {
        writer.print("-----END " + headfoot + "-----\n");
    }
    writer.flush();
    return pemStream.toByteArray();
}


An easier way to do this is not to encrypt, but use an unencrypted button and then a hash trick to detect tampering. I explain this here with PHP, but you can translate to Java.

How do I make a PayPal encrypted buy now button with custom fields?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜