Wednesday, November 28, 2012

Amazon Checkout HMAC-SHA1 With Classic ASP

I've been trying to implement Amazon Checkout for the last few days.  Using Classic ASP it's been a real nightmare: no sample code to work with.

I've finally cracked it with the help of some Google Checkout cryptography libraries , specifically the file "GlobalAPIFunctions.asp" located in the sample code linked to above.

You will also need to get the GCrypt COM object installed on your server.  I had to ask my hosting company to do this, it might already be installed since Google Checkout is popular.

Here is the code that worked.  Before you use it:

  • Download the GlobalAPIFunctions.asp file and install it on your server
  • Edit the include file URL to point to GlobalAPIFunctions.asp
  • Edit the AWSSecretKey, AWSAccessKeyID, and AWSMerchantID variables to match your Amazon Checkout account
  • Make sure GCrypt COM Object is installed
  • Edit the cart XML for your purposes


<!--#include virtual="/api/GlobalAPIFunctions.asp"-->

<%
        'This is a Base64 encode that doesn't put line breaks in like Google's does
Dim Base64Chars
Base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" & _
"abcdefghijklmnopqrstuvwxyz" & _
"0123456789" & _
"+/"


' Functions for encoding string to Base64
Public Function base64_encode( byVal strIn )
Dim c1, c2, c3, w1, w2, w3, w4, n, strOut
For n = 1 To Len( strIn ) Step 3
c1 = Asc( Mid( strIn, n, 1 ) )
c2 = Asc( Mid( strIn, n + 1, 1 ) + Chr(0) )
c3 = Asc( Mid( strIn, n + 2, 1 ) + Chr(0) )
w1 = Int( c1 / 4 ) : w2 = ( c1 And 3 ) * 16 + Int( c2 / 16 )
If Len( strIn ) >= n + 1 Then
w3 = ( c2 And 15 ) * 4 + Int( c3 / 64 )
Else
w3 = -1
End If
If Len( strIn ) >= n + 2 Then
w4 = c3 And 63
Else
w4 = -1
End If
strOut = strOut + mimeencode( w1 ) + mimeencode( w2 ) + _
 mimeencode( w3 ) + mimeencode( w4 )
Next
base64_encode = strOut
End Function

Private Function mimeencode( byVal intIn )
If intIn >= 0 Then
mimeencode = Mid( Base64Chars, intIn + 1, 1 )
Else
mimeencode = ""
End If
End Function


' Function to decode string from Base64
Public Function base64_decode( byVal strIn )
Dim w1, w2, w3, w4, n, strOut
For n = 1 To Len( strIn ) Step 4
w1 = mimedecode( Mid( strIn, n, 1 ) )
w2 = mimedecode( Mid( strIn, n + 1, 1 ) )
w3 = mimedecode( Mid( strIn, n + 2, 1 ) )
w4 = mimedecode( Mid( strIn, n + 3, 1 ) )
If w2 >= 0 Then _
strOut = strOut + _
Chr( ( ( w1 * 4 + Int( w2 / 16 ) ) And 255 ) )
If w3 >= 0 Then _
strOut = strOut + _
Chr( ( ( w2 * 16 + Int( w3 / 4 ) ) And 255 ) )
If w4 >= 0 Then _
strOut = strOut + _
Chr( ( ( w3 * 64 + w4 ) And 255 ) )
Next
base64_decode = strOut
End Function

Private Function mimedecode( byVal strIn )
If Len( strIn ) = 0 Then
mimedecode = -1 : Exit Function
Else
mimedecode = InStr( Base64Chars, strIn ) - 1
End If
End Function

'AMAZON VARS
dim AWSSecretKey
dim AWSAccessKeyID
dim AWSMerchantID
dim AWSSignature
dim AWSCart
dim AWSCartB64

AWSSecretKey = "XXXXXXXXXXXXXXXXXXXXXXX"
AWSAccessKeyID = "123ABCDEFG"
AWSMerchantID = "123XZY"

'AMAZON VARS END

AWSCart = AWSCart & "<?xml version=" & """" & "1.0" & """" & " encoding=" & """" & "UTF-8" & """" & "?>"
AWSCart = AWSCart & "<Order xmlns=" & """" & "http://payments.amazon.com/checkout/2009-05-15/" & """" & ">"
AWSCart = AWSCart & "<Cart>"
AWSCart = AWSCart & "<Items>"

'while 'Iterate through the items in the cart here



'AMAZON ADD ITEM TO CART
AWSCart = AWSCart & "<Item>"
        AWSCart = AWSCart & "<SKU>" & YourSKU & "</SKU>"
        AWSCart = AWSCart & "<MerchantId>" & AWSMerchantID & "</MerchantId>"
      AWSCart = AWSCart & "<Title>" & YourItemName & "</Title>"
        AWSCart = AWSCart & "<Price>"
          AWSCart = AWSCart & "<Amount>" & YourPrice & "</Amount>"
          AWSCart = AWSCart & "<CurrencyCode>USD</CurrencyCode>"
        AWSCart = AWSCart & "</Price>"
        AWSCart = AWSCart & "<Quantity>" & YourQuantity & "</Quantity>"
      AWSCart = AWSCart & "</Item>"

'AMAZON ADD ITEM TO CART END
'wend 'Finished iterating through items in the cart

'AMAZON Process Cart

AWSCart = AWSCart & "</Items>"
  AWSCart = AWSCart & "</Cart>"
AWSCart = AWSCart & "</Order>"

AWSSignature = cryptObj.generateSignature(AWSCart, AWSSecretKey)
AWSCartB64 = base64_encode(AWScart)

set cryptObj = Nothing
%>
<html>
<body>
<!-- AMAZON CHECKOUT BUTTON -->
<script type='text/javascript' src='https://static-na.payments-amazon.com/cba/js/us/sandbox/PaymentWidgets.js'>
</script>

<!-- For Switching to Production, comment out the lines above and uncomment the lines below -->
<!-- <script type='text/javascript' src='https://static-na.payments-amazon.com/cba/js/us/PaymentWidgets.js'>
</script> -->

<div id="cbaButton1">
    <img src="https://payments-sandbox.amazon.com/gp/cba/button?type=cart&cartOwnerId=<%= AWSMerchantID %>&color=orange&size=large&background=white"/>
    <!-- For Switching to Production, comment out the line above and uncomment the line below -->
    <!--<img src="https://payments.amazon.com/gp/cba/button?type=cart&cartOwnerId=<%= AWSMerchantID %>&color=orange&size=large&background=white"/>-->
</div>

<script type='text/javascript'>
  new CBA.Widgets.StandardCheckoutWidget({
    merchantId:'<%= AWSMerchantID %>',
    orderInput: {
        format: "XML",
        value: "type:merchant-signed-order/aws-accesskey/1;order:<%= AWSCartB64 %>;signature:<%= AWSSignature %>;aws-access-key-id:<%= AWSAccessKeyID %>"},
        buttonSettings: { size: 'large',color:'orange',background:'white'}
  }).render("cbaButton1");
</script>
</body>
</html>
<!-- END AMAZON CHECKOUT BUTTON -->

No comments:

Post a Comment