최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday

티스토리 뷰


   Paypal의 마지막 챕터


이제 마지막 마무리다. 


챕터가 총 5개로 분할 되어 혼란스러움을 막기 위해 이번 포스트 에서는 


[페이팔 결제 창 호출] -> [페이팔 IPN 수신 처리] -> [결제 완료 / 결제 취소 / 결제 에러] 까지 직접 코드를 적어보며


실무에서 본인이 그대로 쓴 코드를 소개하고 정리함으로써, 구현과 활용을 바로 할 수 있게 도울 예정이다.


참고로 지난번 포스트 까지의 내용을 일목요연하게 살펴보면...


 주제

소개 내용 

 01. paypal의 테스트 ID만들고, 결제 창 띄워 보기

 테스트 계정 생성과 결제 페이지 HTML로 호출 해 보기

 02. paypal에서 "한글"을 전달할 때 유의사항과 값 넘기기

 인코딩 설정과 ASP로 GET, POST 호출 해 보기

 03. 페이팔 수수료 확인과 USD환율 적용하기

 내 상점의 수수료 확인과 환율 적용 공식 짜기

 04. paypal의 "IPN" 수신하는 2가지 방법

 IPN을 받을 수 있는 2가지 방법 알기




 

   프로그래밍 전 프로세스의 흐름과 준비

 

 

 

여기에서 반드시 알아두어야 할 사항과 의문점을 설명하고 넘어가자면.



① 위의 그림과 같이 쇼핑몰에서 고객이(회원이던 비회원이던) 장바구니에 물건을 담을 경우 


   임시 테이블에 고유한 키(본인은 세션번호로)를 하나 넣어두고 쇼핑 정보를 저장한다.



② 그림과 같이 고객이 결제를 누르면.


   1. 고객이 결제를 클릭하여 페이팔에 결제 요청을 하면 그 즉시 임시 테이블에 일련 번호 코드를 집어넣는다. 


      여기에서 일련 번호 코드란 절대 중복 될 수 없는 형식을 가진 코드 이어야 한다.


      예) 날짜 + 일련번호  = 20140519_101...


      이 일련번호는 만들기 전에 주문 배송이 완료된 테이블에서 select 로 조회하여 +1 정도로 생성하면 될 것이다.


     일련번호를 조회하는 이유는 중복됨을 방지하기 위해서 이며, 일련 번호를 조회하는 대상은 당연히 주문처리가 끝난 테이블에서


     검사를 해야한다. (이해가 안되면 일단 끝까지 읽고나서 다시 읽으면 이해가 될 것이다.)


  2. 이제 일련번호를 쓸 때가 왔다. 만든 일련 번호는 페이팔 매개 변수 중 "invoice" 항목으로 넘겨서 보낸다.


     이 "invoice"코드가 결제가 완료되면 IPN을 통해 우리가 수신 할, 매우 중요한 키다.


    주의 할 점은 한번 매개변수로 전달되어 결제된 invoice코드로는 다시 결제 진행이 되지 않는다. 이는 페이팔 시스템 상 


    같은 invoice코드로는 중복 결제가 안된다는 뜻 이다.



③ paypal 서버에서 -> notify_url 페이지를 호출.


   ①,②의 내용이 어려웠다면 의문이 풀리는 시점이다. 


   그림에서 보면,  1 > 2 > 4 의 경우 "서버와 - 클라이언트" 의 관계 였기 때문에 주고 받은 값에 대해서 계속 찍어볼 수 도 있고 

   

    확인할 수 도 있었다.

  

    그러나.  페이팔에서 결제가 완료되면 IPN이 동작하는데 이것은 "페이팔 - 서버 페이지를 호출" 로 동작한다. 


    그림으로 보면 파란색 점선 윗부분이다. 이부분은 클라이언트에서 확인 할 수가 없다.


    즉 페이팔 서버와 서버끼리의 통신인 것이다. 세션 관계가 클라이언트와는 전혀 상관이 없기 때문에 값을 찍어 보거나 


    확인할 수가 없다.


    정말로 서버끼리 통신이 되고 있는지 로그를 살펴보면 제일 정확한데 여기에서는 windows 서버만 예로 들겠다.


    ㄱ.  윈도우 + R 을 눌러서 실행창을 띄운다. 


    ㄴ. %SystemDrive%\inetpub\logs\LogFiles   을 입력한다.


    ㄷ. 아래와 같은 창이 뜬다. 척봐도 위의 폴더는 FTP라고 적혀있으므로 패스.


ㄹ. log 파일들이 쌓여있다.


   ㅁ. IPN을 테스트한 날짜의 로그 파일을 열어보면 아래와 같이 notify.asp 파일이 호출되었다는 로그를 확인 할 수 있다.




결론은 페이팔이 notify_url페이지를 호출 했을 때 전달한 invoice값을 가지고, 임시 테이블을 invoice로 다시 뒤져서 장바구니 정보를 


알아낸 다음 이것을 최종 주문결제 테이블에 전부 집어 넣고 고객에게 주문 완료 메세지를 발송하고 


임시 테이블은 이제 그만 삭제(Delete)하면 된다.  는 것이다.


참고로 invoice코드는 주문 일련번호로 나중에 검색 할 때 쓸수 있으므로 최종 주문 결제 테이블에도 넣어 놓는 것이 안전하다.


이렇게 결제가 완료되면 반드시 SMS나 이메일로 고객에게 처리 상태를 통보해 주는것이 안전하고 코드상에서 설명 하겠지만


HTTP의 유효성 검사를 통해서 변조되거나 올바르지 않은 프로토콜 응답 번호가 리턴되어 결제가 안되었을 경우 고객에게 


에러 메세지를 전달 해 주면 된다.


정리하면 notify_url의 흐름은


결제가 완료되어 페이팔이 notify_url 페이지를 호출한다 > notify_url에서는 invoice코드를 수신한다. > invoice코드를 임시 장바구니 


테이블에 대고 조회한다. >고유 번호를 얻는다(세션번호) > 고유 번호를 가지고 다시 장바구니를 목록 조회한다. > 조회된 항목 


들을 최종 주문 테이블에 넣는다 >고객에게 주문 완료 메세지를 띄운다.



④ 그럼 그림 4는?


그림 4는 결제 일련의 과정이 끝났음을 의미하는 것이지 실제로 결제 유무는 반드시 IPN을 통해 호출된 notify_url 페이지에서만 


알 수 있다는 것에 유의 해야 한다. 


한마디로 complete따로, IPN따로 각각 별개인 것이다. (저번 시간에 설명 했지만)



(내용추가) 2014 - 11- 24


   IPN (From Paypal Server Parameter)


notify_url 페이지에서 IPN과 더불어 받을 수 있는 파라메터는 다음과 같다.


addr1 = request("address_street") ' 주문자 정보 - 주소

city = request("address_city") ' 주문자 정보 - 도시

company = request("payer_business_name") ' 주문자 정보 - 회사

country = request("address_country") ' 주문자 정보 - 국가

email = request("payer_email") ' 주문자 정보 -  email

orderdate = request("payment_date") ' 주문일

orderid = request("txn_id") ' 상품 주문 id (product order id)

prodid = request("item_number") ' 상품의 id (product id)

qty = request("quantity") ' 주문 수량 (order product quantity)

state = request("address_state") ' 주문자 정보 - state(주)

tot = request("mc_gross") ' 상품의 총 가격 (product total price)

trackingid = request("txn_id") ' order trackin id

ordername = request("last_name") & " " & request("first_name")         ' 주문자 이름

zip = request("address_zip") ' 주문자 정보 - 우편번호 (zip)

payment_status = request("payment_status") ' 주문 상태 (payment status)



   페이팔에서 소개하는 IPN설명과 유효성 처리 방법


페이팔 사이트에서 직접 설명한 IPN의 동작방식과 프로세스


What is PayPal’s IPN (Instant Payment Notification)?

페이팔의 IPN이란 무엇인가?


Instant Payment Notification (IPN) is an “interface for handling real-time purchase confirmation”. 

즉시 지불 알림 (IPN)은 "실시간 구매 확인을 처리하기 위한 인터페이스 핸들링" 입니다.


IPN automatically notifies a defined web page when a PayPal payment has been made to a specific PayPal account and 

IPN은 자동으로 페이팔의 특정 페이팔 계정에 적용된 경우, 정의 된 web페이지를 통지하고


allows your web page to communicate with PayPal’s server to authenticate the validity of that purchase.

당신의 웹 페이지는 해당 구매의 유효성을 인증하기 위해 페이팔 서버와 통신을 할 수 있습니다.


How does IPN work?

IPN작업은 어떻게 합니까?


When a customer makes a payment to you, PayPal will post a notification to your server at a URL you specify in your PayPal account. 

고객이 당신의 웹 사이트에 지불하면 페이팔은 페이팔 계정에 지정된 URL에 엑세스하여 서버에 전송합니다.


Included in this notification will be all of your customer's payment details and product details as well as a piece of encrypted code.

이 공지에 포함 된 것은 당신의 고객이 지불한 상세 정보 및 제품 상세 뿐만 아니라 암호화(혹은 인코딩?)된 코드의 일부입니다.


When your webpage receives a notification, it will then post the information including the encrypted code back to a secure PayPal URL. 

당신의 웹 페이지가 전송 받게 되면 다시 안전한 페이팔 URL에 대한 암호화 코드를 포함하는 정보를 작성합니다.


PayPal will in turn authenticate the transaction and will respond to the post with a single word, "VERIFIED", "INVALID" or “FAILED”.

페이팔이 차례대로 트랜잭션을 인증하면  "VERIFIED", "INVALID" 혹은 “FAILED” 으로 응답합니다.


Your webpage will need a script to handle this IPN and respond in the way you want it to. 

당신의 웹페이지에서는 이 IPN을 처리하고 당신이 원하는 방법으로 응답하는 스크립트가 필요합니다.


Your script can carry out other checks such as making sure that the payment status is complete rather than pending, 

스크립트는 지불 상황이 아닌 보류중인지, 더 완전한지 확인 하는 등 다른 검사를 할 수 있으며,


that the “receiver_email” is your account email and that the price of the product is correct. 

receiver_email은 당신의 계정 이메일 주소와 제품 가격이 맞다는 것을 확인 할 수있다.


Once you have completed the above checks, your script may update your database with the IPN data and process the purchase.

당신은 위의 체크를 완료하면, 당신의 스크립트는 IPN데이터를 사용하여 데이터베이스를 업데이트하고 구매처리를 할 수 있다.


The communication between your webpage and PayPal’s server ensures that the IPN comes from PayPal and prevents “spoofing”.

자신의 웹 페이지나 페이팔 서버 간의 통신은 IPN이 페이팔에서 온 spoofing을 방지하는 것을 보장합니다.


For more information refer to the IPN manual and the PayPal IPN documentation.

자세한 내용은 IPN메뉴얼 및 페이팔의 IPN설명서를 참조 하십시오.


How does IPN work with our MembersPro PayPal script?


그럼 IPN을 어떻게 웹사이트(여기서는  MembersPro로 소개함)  페이팔 스크립트를 사용하여 작성합니까?


A customer selects a membership option that they would like to subscribe to and then fills out the sign up form. 

고객들이 가입 하고 싶다고 하여 양식에 서명을 기입하는 것이다. 멤버쉽 옵션을 선택합니다.


The customer then clicks on the payment button and then goes through with their PayPal payment.

고객은 결제 버튼을 클릭한뒤 해당 페이팔 지불을 통과합니다.


The IPN process and post back as outlined above occur and provided the payment is verified and successful then the new member will be redirected back to the site’s login page and is instantly sent out an autogenerated password via email.

IPN프로세스와 결제 규정의 포스트 백을 확인하고 성공하면 새 멤버가 다시 사이트의 로그인 페이지로 리디렉션 됩니다.

즉시 자동 생성된 비밀번호가 이메일을 통해 보내집니다.


The new member can then login to their account as an active member. Depending on the membership option that the new member has paid for they will be taken to the members home page for that subscription option.

새로운 회원이 자신의 계정에 로그인할 수 있습니다. 새로운 멤버가 지불한 회원의 옵션에 따라 서브 스크립션의 홈페이지로 이동합니다.


페이팔에서 추천하는 IPN의 유효성 검사와 결제 성공여부 판단.


paypal IPN script.asp  : ASP 버전 


<%@LANGUAGE="VBScript"%>

<%

Dim Item_name, Item_number, Payment_status, Payment_amount

Dim Txn_id, Receiver_email, Payer_email

Dim objHttp, str


'read post from PayPal system and add 'cmd' : 페이팔 시스템에서 CMD를 추가

str = Request.Form & "&cmd=_notify-validate"


'post back to PayPal system to validate : 확인하기 위해 페이팔 시스템에 다시 전송

set objHttp = Server.CreateObject("Msxml2.ServerXMLHTTP")

'set objHttp = Server.CreateObject("Msxml2.ServerXMLHTTP.4.0")

'set objHttp = Server.CreateObject("Microsoft.XMLHTTP")

objHttp.open "POST", "https://www.paypal.com/cgi-bin/webscr", false

objHttp.setRequestHeader "Content-type", "application/x-www-form-urlencoded"

objHttp.Send str


'assign posted variables to local variables : 로컬 변수에 게시된 변수를 대입

Item_name = Request.Form("item_name")

Item_number = Request.Form("item_number")

Payment_status = Request.Form("payment_status")

Payment_amount = Request.Form("mc_gross")

Payment_currency = Request.Form("mc_currency")

Txn_id = Request.Form("txn_id")

Receiver_email = Request.Form("receiver_email")

Payer_email = Request.Form("payer_email")


'Check notification validation : 알림의 유효성을 확인

if (objHttp.status <> 200 ) then

'HTTP error handling : HTTP 오류 처리

elseif (objHttp.responseText = "VERIFIED") then

'check that Payment_status=Completed : complete되었는지 확인

'check that Txn_id has not been previously processed : Txn_id가 이전에 처리되었는지 확인

'check that Receiver_email is your Primary PayPal email : Receiver_email이 당신의 페이팔 메일인지 확인

'check that Payment_amount/Payment_currency are correct : Payment_amount / Payment_currency 이 올바른지 확인 하십시오

'process payment

elseif (objHttp.responseText = "INVALID") then

'log for manual investigation : 직접 조사를 위해 로그

else

'error : 에러

end if

set objHttp = nothing

%>



paypal_ipn.php : PHP 버전


<?php


// CONFIG: Enable debug mode. This means we'll log requests into 'ipn.log' in the same directory.

// Especially useful if you encounter network errors or other intermittent problems with IPN (validation).

// Set this to 0 once you go live or don't require logging.

define("DEBUG", 1);


// Set to 0 once you're ready to go live

define("USE_SANDBOX", 1);



define("LOG_FILE", "./ipn.log");



// Read POST data

// reading posted data directly from $_POST causes serialization

// issues with array data in POST. Reading raw POST data from input stream instead.

$raw_post_data = file_get_contents('php://input');

$raw_post_array = explode('&', $raw_post_data);

$myPost = array();

foreach ($raw_post_array as $keyval) {

$keyval = explode ('=', $keyval);

if (count($keyval) == 2)

$myPost[$keyval[0]] = urldecode($keyval[1]);

}

// read the post from PayPal system and add 'cmd'

$req = 'cmd=_notify-validate';

if(function_exists('get_magic_quotes_gpc')) {

$get_magic_quotes_exists = true;

}

foreach ($myPost as $key => $value) {

if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {

$value = urlencode(stripslashes($value));

} else {

$value = urlencode($value);

}

$req .= "&$key=$value";

}


// Post IPN data back to PayPal to validate the IPN data is genuine

// Without this step anyone can fake IPN data


if(USE_SANDBOX == true) {

$paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";

} else {

$paypal_url = "https://www.paypal.com/cgi-bin/webscr";

}


$ch = curl_init($paypal_url);

if ($ch == FALSE) {

return FALSE;

}


curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);

curl_setopt($ch, CURLOPT_POST, 1);

curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);

curl_setopt($ch, CURLOPT_POSTFIELDS, $req);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);

curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);


if(DEBUG == true) {

curl_setopt($ch, CURLOPT_HEADER, 1);

curl_setopt($ch, CURLINFO_HEADER_OUT, 1);

}


// CONFIG: Optional proxy configuration

//curl_setopt($ch, CURLOPT_PROXY, $proxy);

//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);


// Set TCP timeout to 30 seconds

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);

curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));


// CONFIG: Please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path

// of the certificate as shown below. Ensure the file is readable by the webserver.

// This is mandatory for some environments.


//$cert = __DIR__ . "./cacert.pem";

//curl_setopt($ch, CURLOPT_CAINFO, $cert);


$res = curl_exec($ch);

if (curl_errno($ch) != 0) // cURL error

{

if(DEBUG == true) {

error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);

}

curl_close($ch);

exit;


} else {

// Log the entire HTTP response if debug is switched on.

if(DEBUG == true) {

error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE);

error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE);


// Split response headers and payload

list($headers, $res) = explode("\r\n\r\n", $res, 2);

}

curl_close($ch);

}


// Inspect IPN validation result and act accordingly


if (strcmp ($res, "VERIFIED") == 0) {

// check whether the payment_status is Completed

// check that txn_id has not been previously processed

// check that receiver_email is your PayPal email

// check that payment_amount/payment_currency are correct

// process payment and mark item as paid.


// assign posted variables to local variables

//$item_name = $_POST['item_name'];

//$item_number = $_POST['item_number'];

//$payment_status = $_POST['payment_status'];

//$payment_amount = $_POST['mc_gross'];

//$payment_currency = $_POST['mc_currency'];

//$txn_id = $_POST['txn_id'];

//$receiver_email = $_POST['receiver_email'];

//$payer_email = $_POST['payer_email'];

if(DEBUG == true) {

error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req ". PHP_EOL, 3, LOG_FILE);

}

} else if (strcmp ($res, "INVALID") == 0) {

// log for manual investigation

// Add business logic here which deals with invalid IPN messages

if(DEBUG == true) {

error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE);

}

}


?>




어떤 분이 작성(출처는 확인 후 바로 조치하겠습니다.) 했었던 IPN관련 처리 코드 샘플.


(결제확인 -> 유효성검사 -> DB에서 중복 주문을 조회 ->  결제 유효성 조회 -> 고객에게 메세지(성공/오류) 내용이 들어가 있으며



<%@LANGUAGE="VBScript"%>


<%

dim addr1, city, company, country, email, orderdate

dim orderid, prodid, qty, state, tot, trackingid

dim ordername, zip, payment_status, ret, msg, str

dim connString, conn, objHttp, SQL

' email 정보

const myEmail = "myemail@mydomain.com"

const myEmailLogin = "mylogin"

const myEmailPassword = "mypassword"

const mySMTPServer = "smtp.mydomain.com"

const myDomain = "http://www.mydoamin.com"

' 데이터베이스 (MS-ACCESS) 정보

const myDatabasePath = "/database"

const connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data source=%database%;Jet OLEDB:Database Password=;"

' MS-SQL

'const connString = "Provider=SQLOLEDB;Data Source=serverName;Initial Catalog=databaseName;User ID=MyUserID;Password=MyPassword;"

' ORACLE

'const connString = "Provider=MSDAORA;Data Source=serverName;User ID=MyUserID;Password=MyPassword;"

' MySQL

'const connString = "Provider=MySQLProv.2.5;Data Source=serverName;UID=myUserID;PWD=MyPassword"

' 링크 파라미터를 가져오는 부분 (retrtieve link parameters)

addr1 = request("address_street") ' 주문자 정보 - 주소

city = request("address_city") ' 주문자 정보 - 도시

company = request("payer_business_name") ' 주문자 정보 - 회사

country = request("address_country") ' 주문자 정보 - 국가

email = request("payer_email") ' 주문자 정보 -  email

orderdate = request("payment_date") ' 주문일

orderid = request("txn_id") ' 상품 주문 id (product order id)

prodid = request("item_number") ' 상품의 id (product id)

qty = request("quantity") ' 주문 수량 (order product quantity)

state = request("address_state") ' 주문자 정보 - state(주)

tot = request("mc_gross") ' 상품의 총 가격 (product total price)

trackingid = request("txn_id") ' order trackin id

ordername = request("last_name") & " " & request("first_name") ' 주문자 이름

zip = request("address_zip") ' 주문자 정보 - 우편번호 (zip)

payment_status = request("payment_status") ' 주문 상태 (payment status)


' html 이메일 보내기 (send html email)

function SendEmail(byval emailaddr, byval message)

on error resume next

Set iMsg = CreateObject("CDO.Message")

Set iConf = CreateObject("CDO.Configuration")

Set Flds = iConf.Fields


schema = "http://schemas.microsoft.com/cdo/configuration/"

Flds.Item(schema & "sendusing") = 2

Flds.Item(schema & "smtpserver") = mySMTPServer

Flds.Item(schema & "smtpserverport") = 25

Flds.Item(schema & "sendusername") = myEmailLogin

Flds.Item(schema & "sendpassword") = myEmailPassword

Flds.Item(schema & "smtpauthenticate") = 1

Flds.Update


With iMsg

.To = emailaddr

.From = myEmail

.Subject = "PayPal Payment"

.HTMLBody = message

.Sender = myDomain

.HTMLBody = message

Set .Configuration = iConf

SendEmail = .Send

End With

on error goto 0

end function

' 페이팔 결재 확인 (PayPal verification)

set objHttp = Server.CreateObject("Msxml2.ServerXMLHTTP")

if err.number <> 0 then set objHttp = Server.CreateObject("Microsoft.XMLHTTP")

str = Request.Form & "&cmd=_notify-validate"

objHttp.open "POST", "https://www.paypal.com/cgi-bin/webscr", false

objHttp.setRequestHeader "Content-type", "application/x-www-form-urlencoded"

objHttp.Send str

if objHttp.status <> 200 then

set objHttp = nothing

Response.Redirect "error.asp"

end if

ret = objHttp.responseText

set objHttp = nothing


' 고객 정보와 관리 메시지를 보낸다. (send administrative message with customer informations)

msg = "<b>Customer Informations from PayPal</b><br><br>"

msg = msg & "       Name: " & ordername & "<br>"

msg = msg & "    Company: " & company & "<br>"

msg = msg & "  Address 1: " & addr1 & "<br>"

msg = msg & "       City: " & city & "<br>"

msg = msg & "    Country: " & country & "<br>"

msg = msg & "      State: " & state & "<br>"

msg = msg & "        Zip: " & zip & "<br>"

msg = msg & "      Email: " & email & "<br>"

msg = msg & " Order Date: " & orderdate & "<br>"

msg = msg & "   Order ID: " & orderid & "<br>"

msg = msg & "Tracking ID: " & trackingid & "<br>"

msg = msg & " Product ID: " & prodid & "<br>"

msg = msg & "   Quantity: " & qty & "<br>"

msg = msg & "      Total: " & tot & "<br>"

msg = msg & "     Status: " & payment_status & "<br>"

SendEmail myEmail, msg


' 통지 유효성 검사 (Check notification validation)

if (ret = "VERIFIED") then


' 주문이 유효한지 검사 (다음중에 해당이 없으면 에러메시지를 보낸다.)

if instr("CANCELED_REVERSAL COMPLETED DENIED FAILED PENDING REFUNDED REVERSED PROCESSED",ucase(payment_status))=0 then

Response.Redirect "error.asp" 

end if


' 데이터베이스 open

set conn = CreateObject("ADODB.Connection")

conn.Open replace(connString,"%database%",Server.MapPath(myDatabasePath & "/customer.mdb")),"Admin"

'앞에것이 안된다면 아래꺼 쓰면 되겠음.

'conn.Open connString

if err.number <> 0 then

set conn = nothing

Response.Redirect "error.asp"

end if


' 테이블 open

set rs = Server.CreateObject("ADODB.Recordset")

rs.Open "Customer", conn, 2, 3

' 주문이 이미 DB에 있는지 확인

rs.Find "orderid=" & orderid

if rs.EOF then

' 없다면 새로운 결재 정보를 삽입한다.

conn.BeginTrans

rs.AddNew

rs("addr1") = addr1

rs("city") = city

rs("company") = company

rs("country") = country

rs("orderdate") = orderdate

rs("email") = lcase(email)

rs("orderid") = orderid

rs("prodid") = prodid

rs("qty") = qty

rs("state") = state

rs("tot") = tot

rs("trackingid") = trackingid

rs("name") = ordername

rs("zip") = zip

rs("status") = payment_status

rs.Update 


' 에러가 있다면...........

if err.number <> 0 then

' 결재 취소

conn.RollbackTrans 

' 테이블 닫는다.

rs.Close

set rs = nothing

' DB닫는다.

conn.Close

set conn = nothing

' 에러메시지 표시하는 페이지로 리디렉트

Response.Redirect "error.asp"

end if

' 에러가 없다면 거래확인

conn.CommitTrans 

end if

' 테이블 닫고

rs.Close

set rs = nothing

' DB도 닫고

conn.Close

set conn = nothing


        ' 지불의 무효 또는 환불(invalid payment or refunded) (다음중에 하나에 걸리면 그건 에러니까.......에러메시지를 뿌린다.)

if bexist and instr("CANCELED_REVERSAL DENIED FAILED REFUNDED REVERSED", ucase(payment_status))>0 then

Response.Redirect "error.asp"

end if


' 해결되지 못한 주문이 있는가(not pending order)

if ucase(payment_status) <> "PENDING" then

   ' 고객에게 확인 메일을 발송한다.

   msg = "<b>고객님은 " & myDomain & "에서 결재하셨습니다.<br><br><br>"

   msg = msg & "고객님께,<br>"

   msg = msg & "주문이 잘 이루어 졌음을 알립니다.<br>"

   'msg = msg & "If you need further help, please contact us at <a href=""mailto:" & myEmail & """>" & myEmail & "</a><br><br>"

   msg = msg & "감사합니다.<br>"

   SendEmail email, msg

end if

else

' 고객에게 에러 메일을 발송한다.

msg = "<b>고객님이 " & myDomain & "에서 결재 처리하는데 있어 오류가 발생했습니다.<br><br><br>"

msg = msg & "고객님께,<br>"

msg = msg & "고객님의 결재를 처리하는 과정에 문제가 발생했습니다. 고객님의 <a href=""www.paypal.com"">PayPal</a> 계정을 확인해 주시기 바랍니다.<br>"

msg = msg & "도움이 필요하시면 <a href=""mailto:" & myEmail & """>" & myEmail & "</a>로 문의해주시기 바랍니다.<br><br>"

msg = msg & "감사합니다.<br>"

SendEmail email, msg

end if

%>


<html>

<body bgcolor="#ffffff">

<center>

<table border="0" width="80%">

<tr>

<td align="left"><%=msg%></td>

</tr>

</table>

</center>

</body>

</html>




   1-1. 장바구니

 

코드준비중

   1-2. 페이팔 결제 창 호출하기


코드준비중


   2. 페이팔 IPN 수신 처리하기


코드준비중


   3. "결제 완료 / 결제 취소 / 결제 에러" 처리하기


코드준비중



댓글