最好的方法是使用用户角色来处理这个问题。用户可以注册,但不能读取。使用paypal付款后,角色将更新(例如,从读者到订阅者)。更新可以通过PayPals IPN完成。
这是我为我的一个客户做的。您将由您的客户支付。我将由你支付。你有插件了。
Update
由于你想写一个主题,而不是将其用于你的专业业务,这里是我的插件解决方案的一些部分。
PayPal IPN
让我们从贝宝IPN开始。贝宝有一个完善的API和
PayPal Developer Network. 开发人员网络中的一个帐户将对您有很大帮助,贝宝提供了一个沙盒和许多脚本和教程<通过开发人员网络挖掘,我找到了IPN(即时支付通知)。IPN意味着,PayPal向您在PayPal Account中指定的url发送一个包含付款人详细信息的post请求。在开发过程中,您会喜欢
IPN simulator.<让我们开始第一个实验脚本。转到PayPal IPN模拟器(参见上面的链接)。模拟器需要的第一件事是脚本的url。贝宝通过post请求发送数据,因此您不能使用本地Web服务器,您需要一个公共Web服务器。假设您的服务器在
http://yourdoma.in
, 然后用ftp上传下面的脚本(例如命名它
pplog.php
) 并输入
http://yourdoma.in/pplog.php
进入现场或
IPN handler URL
. 选择
Cart checkout
从下一个下拉菜单中按
Send IPN
<?php
if (empty($_POST))
exit( \'No post request\' );
define(\'MAILMODE\', true);
$filename = \'paypal-ipn.log\';
$file_exists = file_exists(filename);
if ($file_exists && MAILMODE) {
unlink($filename);
$mode = \'w\';
} else {
$mode = $file_exists ? \'a+\' : \'w\';
}
$handle = fopen($filename, $mode);
if ( $handle ) {
fputs($handle, date( \'Y-m-d\')."\\n");
fputs($handle, var_export( $_POST, true));
fputs($handle, "\\n");
fputs($handle, str_repeat(\'-\', 80)."\\n");
fclose($handle);
}
if (MAILMODE)
mail(\'[email protected]\', \'PayPal IPN Log\', file_get_contents($filename));
脚本应发送一封电子邮件,其中包含贝宝作为post请求发送的数据。电子邮件到达并打开后,您将看到大量数据。我们只需要一小部分,不要生气。我们只是对
last_name
,
first_name
和
payer_email
.
现在我们必须对接收到的post数据进行处理。首先,您可以验证post数据。如果您认为数据正常,没有人会对您进行治疗,请跳过下一步。如果您知道每个人都可以发送包含所需post数据的post请求(因为您的主题是开源的),那么您必须验证post数据
要验证收到的数据,我们必须将其发送回贝宝。贝宝将回答VERIFIED
或INVALID
. 下一个代码段来自PayPal开发人员网络
class PayPal_IPN_API
{
//const PAYPALURI = \'ssl://www.sandbox.paypal.com\';
const PAYPALURI = \'ssl://ipnpb.paypal.com\';
private function talk_to_paypal() {
/*
* Original code from PayPal Developer Network
*/
// read the post from PayPal system and add \'cmd\'
$req = \'cmd=_notify-validate\';
foreach( $_POST as $key => $value ){
$value = urlencode( stripslashes( $value ) );
$req .= "&$key=$value";
}
// post back to PayPal system to validate
$header = "POST /cgi-bin/webscr HTTP/1.0\\r\\n";
$header .= "Content-Type: application/x-www-form-urlencoded\\r\\n";
$header .= "Content-Length: " . strlen( $req ) . "\\r\\n\\r\\n";
$fp = fsockopen( self::PAYPALURI, 443, $errno, $errstr, 30 );
/*
* End PayPal Developer Code
*/
}
}
这个代码片段来自我使用的一个类。在课程开始时,您可以看到
const PAYPALURI
. 贝宝(PayPal)提供了一个沙盒(需要帐户),因此您可以测试您的Scrxript,而无需处理“真实”数据。我将此代码保持原样,可以对其进行优化,而不是使用
fsockopen()
, 您也可以使用
wp_remote_get()
.
现在我们必须处理贝宝的答案,下一个代码片段再次来自我的课堂:
/*
* Modified PayPal Developer Code
*/
if( ! $fp ){
$this->log( "connection failed" );
die( "Can not open connection to PayPal" );
} else {
fputs( $fp, $header . $req );
while( ! feof( $fp ) ){
$res = fgets( $fp, 1024 );
// the received data was verified by PayPal
if( strcmp( $res, "VERIFIED" ) == 0 ){
$payment_status = isset( $_POST[\'payment_status\'] ) ? strtolower( $_POST[\'payment_status\'] ) : \'\';
// check payment status. only completed payments will be processed
if( \'completed\' == $payment_status ){
// create the userdata-array
$udata = array(
\'payer_email\' => $_POST[\'payer_email\'],
\'first_name\' => $_POST[\'first_name\'],
\'last_name\' => $_POST[\'last_name\']
);
$this->modify_wp_user( $udata );
}
// the received data could not be verified by PayPal
} elseif( strcmp( $res, "INVALID" ) == 0 ){
$this->log( "invalid request" );
die( "Invalid request at PayPal" );
} else {
// something went terrible wrong
$this->log( "unknown error while connection" );
}
}
}
// be nice. close the connections you have opened
fclose( $fp );
/*
* End modified PayPal Code
*/
安静简单。检查连接是否成功。如果是,请检查答案。如果答案是
INVALID
, 什么都不做。如果是的话
VERIFIED
, 从第一个post请求中获取付款人的名字和姓氏以及电子邮件地址。
Creating or updating an user
现在我们有了名称和电子邮件地址,所以我们可以创建用户或更新现有用户。基本上,您必须找到具有给定数据的用户。如果存在现有用户,请更新该用户。否则创建新用户
可以通过名字和姓氏获取用户,但这不是本文的主题。我们做的很简单,并试图通过我们刚刚收到的电子邮件地址获取用户。这很容易,因为WordPress有一个很好的功能:
get_user_by()
. 在上面,我们复制了一个数组中的名称和电子邮件地址,并将此数组传递给方法
modify_wp_user()
/**
*
* Create or modify the WP-user
* If the user already exists, the method will upgrade the user
* to a higher user-role.
* If the user does not exists, the method create an user with
* the email as user-name, first and last name and the predefined
* user-role. The password should be send via email to the user!
*
* @param array $userdata Array with the user-email, first and last name.
* @access private
* @since 0.1
*/
private function modify_wp_user( $userdata = array() ) {
if( empty( $userdata ) )
return FALSE;
else
extract( $userdata );
$user = get_user_by( \'email\', $userdata[\'payer_email\'] );
if ( ! $user ) {
$random_password = wp_generate_password( $length=12, $include_standard_special_chars=false );
$data = array(
\'user_pass\' => $random_password,
\'user_login\' => $payer_email,
\'user_email\' => $payer_email,
\'first_name\' => $first_name,
\'last_name\' => $last_name,
\'role\' => \'subscriber\' // adjust the role to your needs
);
wp_insert_user( $data );
} else {
$data = array(
\'ID\' => $user->ID,
\'role\' => \'contributor\' // adjust the role to your needs, maybe use a custom role
);
wp_update_user( $data );
}
}
这是一个简单的开关。获取用户并更新或创建。在这个解决方案中,付款人必须在贝宝和博客中使用相同的电子邮件地址。当创建新用户时,登录名与电子邮件地址相同(从贝宝发送)。
The API endpoint
好了,我们现在有了一个到贝宝的接口。如果付款人付款,PayPal会通过post请求向我们发送数据。我们可以处理数据(验证数据、创建新用户或更新现有用户)<下一个问题可能是最大的问题。您必须创建PayPal将数据发送到的端点。你还记得
IPN handler URL
? 你还记得我在开头发布的第一个脚本吗
现在您必须创建一个端点,例如
http://customer-website.tld/paypalapi
. 此端点是IPN处理程序URL。你可以用WordPress函数来实现这一点
good answers on WPSE on this topic. 我不会在这里讨论这个问题
创建端点并将其指向php文件后,使用第一个脚本进行测试。通过这种方式,您可以轻松测试端点是否工作以及是否存在所需的数据
如果您的端点正常工作,并且您收到了所需的数据,请使用上述两种方法替换脚本,但请使用沙盒url而不是“实时”url。现在登录您的PayPal开发人员帐户并创建一些付款。使用沙盒URL,您可以获得良好的开发和测试环境。
Summary
<首先,您应该在PayPals开发者网络注册,以访问示例脚本、sandox和更多内容创建一个脚本来测试来自贝宝的post请求是否到达。开始测试一些IPN模拟创建一个脚本,根据PayPal发送的数据注册或更新WordPress用户创建一个端点作为PayPal IPN post请求的目标。将所有这些放在一起,用PayPal沙盒进行测试