Skip to content

Instantly share code, notes, and snippets.

@alpeb
Created December 25, 2012 15:40
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save alpeb/4373780 to your computer and use it in GitHub Desktop.
Save alpeb/4373780 to your computer and use it in GitHub Desktop.
package controllers
import play.api._
import play.api.mvc._
import org.apache.commons.httpclient.HttpClient
import org.apache.commons.httpclient.methods.GetMethod
import models.Purchase
object Paypal extends Controller {
val url = "https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate&";
//val url = "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_notify-validate&";
def ipn = Action(parse.raw) {request =>
request.body.asBytes() match {
case Some(arrBytes) => {
val queryString = new String(arrBytes);
Logger.info("Paypal request: " + queryString)
Logger.info("Verifying request: " + url + queryString)
// for some reason I always get invalid if I use play.api.lib.ws.WS instead...
val client = new HttpClient
val methodGet: GetMethod = new GetMethod(url + queryString)
client.executeMethod(methodGet)
val response = methodGet.getResponseBodyAsString
methodGet.releaseConnection
if (response.trim != "VERIFIED") {
logAndFail("Couldn't verify paypal call", "Verification response: " + response.trim)
} else {
val res = queryString.split('&') map { str =>
val pair = str.split('=')
if (pair.length == 2)
(pair(0) -> pair(1))
else
(pair(0) -> "")
} toMap;
if (res.get("payment_status").exists(_ == "Completed")) {
res.get("custom") match {
case Some(custom) => custom.split("_").toList match {
case List("purchase", "id", id) => {
Purchase.getById(id.toLong) match {
case Some(purchase) => {
purchase.setPaid()
// here email the purchase receipt or whatever
Ok
}
case None => logAndFail("Could not find purchase in DB")
}
}
case _ => throw new RuntimeException("invalid custom payload")
}
case None => logAndFail("custom var not available")
}
} else Ok
}
}
case None => logAndFail("Couldn't process paypal ipn")
}
}
private def logAndFail(msg: String, extraMsg: String = "") = {
Logger.warn(msg + " " + extraMsg)
BadRequest(msg)
}
}
@alpeb
Copy link
Author

alpeb commented Dec 25, 2012

The purchase is identified by a custom var sent to paypal "purchase_id_x" where x is the Purchase object ID.

@mslinn
Copy link

mslinn commented Dec 26, 2012

Thanks, I'll play with this

@ygabo
Copy link

ygabo commented Oct 4, 2013

Anyone have this for Java?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment