SmallMerchant is a VisualWorks framework for processing payments through payment processing systems. Currently SmallMerchant only supports portions of Paypal's Website Payments Pro. Depending on your Payment Processing needs, you may find that you need to fill in some of the gaps in SmallMerchant. Please contribute your changes back!
SmallMerchant is free (see the license information in the source bundle) but Paypal Website Payments Pro is not. At the time of this writing it is US$30 per month with an additional 2.2% - 2.9% + US$0.30 per transaction. Details are provided by Paypal during the registration process.
I don't have any specific plan in this regard at the moment but the design of SmallMerchant should allow the integration of other PPS's without too much work. If you need to access another PPS and don't want to implement it yourself, contact me. My consulting fee is reasonable. :-)
If you implement support for another PPS, I would really like you to contribute your work back to SmallMerchant. Just publish it in the Cincom Repository. This is certainly not a requirement of the license and I understand that some employment situations make this impossible.
Probably. SmallMerchant is available under the MIT license. See package comments for details.
Currently only VisualWorks 7.6 and 7.7 are supported.
I recommend that you start by reading the Website Payments Pro integration guide. This guide discusses how you will integrate Paypal into your web site. Note that Website Payments Pro requires that you provide the "express checkout" option to your customers. It is your responsibility to meet the terms of the Website Payment Pro agreement. SmallMerchant enables you to perform express checkout but it doesn't automatically provide this functionality in your application.
Note: If you have problems during this process, please try clearing your browser cookies and cache. In my experience the sandbox is extremely unreliable for creating Website Payment Pro accounts. I posted my problems to the support group and was given this feedback from a paypal developer: Can't create WPP account in sandbox. You should expect to have to contact Paypal to get Website Payments Pro enabled on your sandbox account. Rest assured that the sandbox works very well (it is just the account creation process that is problematic).
The Paypal sandbox permits developers to experiment with Paypal and test their application without any real money being exchanged. In the following text I make reference to two account types:
You should begin by creating a Paypal developer account (bookmark this link...you'll use it a lot!). Even if you already have a Paypal account you need to create a separate developer account. You may use the same e-mail address for both your normal paypal account and your developer account.
From within your developer account you'll need to create "fake" accounts for a single seller and as many buyers as you like (you may need buyer accounts to generate sandbox credit card numbers and to test your support for Paypal Express). Read the Paypal Sandbox User's Guide for instructions.
To perform a transaction on behalf of your seller account you need the API credentials for this seller. You should be able to obtain those by clicking on the "API Credentials" link in your developer sandbox account menu:
Clicking on that link should present you with the credentials for your sandbox seller account:
You will need these credentials to perform transactions with SmallMerchant. I will call them your "seller credentials".
Go back to the "Test Accounts" section (using the top-left menu). You should now log into your seller account by selecting it and clicking the "Enter Sandbox Test Site" button. Your username should be completed for you. The password is the one you chose when you created the account (not your API password!). Once logged in you are looking at a merchant's view of a Paypal account. Use this to look at transactions made against this account. See the sandbox user's guide for more details.
Load the bundle
SmallMerchant-Development from the
Cincom Public Store Repository. This bundle contains both the
SmallMerchant bundle and the
package. If you want to run the SUnit tests, go ahead. You will
be prompted for your seller credentials (username, password and
signature). If you enter one of them incorrectly, you can reset
the test credentials by evaluating the following expression:
If the acceptance tests fail, double check your seller signature on your API credentials page. Some web browsers cut off this long string. You might need to view the HTML source to get the full string. The tests will modify your seller account balance so don't be surprised if it isn't zero any more.
This is a quick example of how to use a payment gateway. Evaluate the following code and "inspect" the result:
gw := WebsitePaymentsPro username: 'your-seller-username' password: 'your-seller-api-password' signature: 'your-seller-signature'. gw useSandbox. gw getBalance inCurrency: SMCurrency usd
In the resulting inspector you'll see that you got back
SMMoney instance. It should correspond to the
account balance you get from the web interface for your seller
SmallMerchant avoids interpreting monetary values going to or
coming from the Payment Processing System. Monetary amounts,
along with their currencies, are stored as strings in instances
SMMoney. Here's a sample of creating
SMMoney instance representing US$100:
amount := SmallMerchant.SMMoney amount: '100.00' currency: SMCurrency usd
SmallMerchant includes the
Address classes for representing a Buyer and
their addresses. Only two buyer addresses are relevant to any
transaction currently supported by SmallMerchant: shipping and
billing. Buyer has accessors for each of these address. Here is
a sample of creating a buyer:
(address := SmallMerchant.Address new) name: 'Fred Jones'; street: '123 N. Main St.'; street2: 'Apt 4'; city: 'New Wilmington'; state: 'PA'; country: (Country withCode: 'US'); phoneNumber: '412-555-1212'; zip: '16172'. (buyer := SmallMerchant.Buyer new) firstName: 'Bob'; lastName: 'Smith'; shippingAddress: address; billingAddress: address.
Notice that the address can specify different names than the buyer. This is to support the ability of Paypal (and probably other PPS's) to list a different name on a shipping label or credit card verification.
Since the seller identity is generally part of the authentication process for the PPS, there is no separate class to represent the seller (see "Seller credentials" below).
Credit cards are commonly used during PPS transactions.
SmallMerchant includes the
CreditCard class. Here is
a sample instance:
(creditCard := SmallMerchant.CreditCard new) name: 'Foo S. Bar'; number: '2222111122223333'; type: SmallMerchant.CreditCardType visa; verificationCode: '111'; expirationMonth: 6; expirationYear: 2012.
PaymentDescription is used in several
places to describe a payment to be made using the PPS. Here is a
sample of creating a simple payment description:
(payment := SmallMerchant.PaymentDescription new) amount: amount; buyer: buyer; ipAddress: '22.214.171.124'; creditCard: creditCard.
For Paypal at least, the IP Address of the computer used by the buyer is supposed to be included in the payment description.
All that is needed to act on behalf of the seller is their credentials. As discussed above these credentials are: username, API password, and API signature. A credentials instance is created as follows:
(credentials := SmallMerchant.Paypal.Credentials new) login: 'Your api username here'; password: 'Your api password here'; signature: 'Your api signature here'.
All transactions are initiated through a payment gateway. The only existing concrete gateway is SmallMerchant.Paypal.WebsitePaymentsPro typically created using a credentials instance as:
gateway := SmallMerchant.Paypal.WebsitePaymentsPro credentials: credentials.
Most payment processing systems provide some sort of sandbox for
testing. To connect the above gateway to a sandbox, rather than the
live site, send it
Transactions and queries are issued via a PPS gateway. All
concrete gateways in SmallMerchant are subclasses of the
PaymentGateway class. The only concrete
gateway included in SmallMerchant right now
An example was already given Quick demo:
Performing a balance inquiry. There is one generic
PaymentGateway API method for fetching your account
#getBalance. Paypal also provides a balance inquiry
that returns your balance in multiple currencies. This
Paypal-specific balance inquiry method
#getBalanceAllCurrencies:. Using the gateway
created above (make sure you sent it #useSandbox) inspect the result
of the following:
response := gateway getBalanceAllCurrencies: true
You should receive an instance
GetBalanceResponse. You can get the balances by
response amounts inspect
or you can get the amount of any specific currency by sending
response inCurrency: SMCurrency usd
which answers a string with the balance in the specified currency (or an error if there are no balances listed in that currency).
Payments are specified by instances
Payment description for an example
of creating a
PaymentDescription. Assuming you have
such a object in a variable called
payment you can post
this payment to your payment gateway via:
gateway post: payment
If you used the
CreditCard instance that I created
above, you may get an error because the credit card number is
invalid. It is worth studying this error because any applications
that use SmallMerchant will need to be able to handle errors. We
will discuss error processing in the Errors
section. In the mean time you can find a valid sandbox credit card
number by logging into your paypal sandbox account, selecting the
"Test Accounts" tab and then picking "View Details" for one of you
accounts. Here is a complete example of posting a payment. You
will have to insert the credit card and API credentials:
(address := SmallMerchant.Address new) name: 'Fred Jones'; street: '123 N. Main St.'; street2: 'Apt 4'; city: 'New Wilmington'; state: 'PA'; country: (SmallMerchant.Country withCode: 'US'); phoneNumber: '412-555-1212'; zip: '16172'. (buyer := Buyer new) firstName: 'Bob'; lastName: 'Smith'; shippingAddress: address; billingAddress: address. (creditCard := CreditCard new) name: 'Foo S. Bar'; number: 'Insert your sandbox credit card number here'; type: SmallMerchant.CreditCardType visa; verificationCode: '111'; expirationMonth: insert your credit card expiration month number here; expirationYear: insert your credit card expiration year number here. (payment := SmallMerchant.PaymentDescription new) amount: (SMMoney amount: '100.0' currency: SMCurrency usd); buyer: buyer; ipAddress: '126.96.36.199'; creditCard: creditCard. (credentials := SmallMerchant.Paypal.Credentials new) login: 'your API username'; password: 'your API password'; signature: 'your API signature'. gateway := SmallMerchant.Paypal.WebsitePaymentsPro credentials: credentials. gateway useSandbox. gateway post: payment.
Often times web boutiques use two phase payment processing. During the order phase, the buyer's payment information is captured and a payment authorization is obtained from the payment processing system. The authorization process normally yields some sort of authorization token. At the time the order is fulfilled the payment is captured using this authorization token. At the time of payment capture the credit card account is debited the total order amount (which may differ from the original authorization amount).
A payment is authorized via the #authorize: method in the gateway:
token := gw authorize: payment.
and later the payment is captured using #capture: which requires a SmallMerchant.PaymentCapture instance as its argument:
(capture := SmallMerchant.PaymentCapture new) amount: (SMMoney amount: '110.00' currency: SMCurrency usd); authorizationId: token transactionId; descriptionOnCreditCardStatement: 'Foo bar'. gw capture: capture
Notice that, in this example, we captured a slightly different amount than we authorized. Often times authorization happens at the time an order is placed and capture occurs when the order is fulfilled. Sometimes there are additional charges that occur during fulfillment (such as shipping charges) that can be captured with the same authorization. Read the Website Payments Pro documentation to determine the limits in differences between the authorize and capture amounts.